20180929 first commit
This commit is contained in:
224
src/AV_interface.h
Normal file
224
src/AV_interface.h
Normal file
@@ -0,0 +1,224 @@
|
||||
#ifndef _AV_INTERFACE_H
|
||||
#define _AV_INTERFACE_H
|
||||
|
||||
#define K_PROJECT 0 //<2F>Ƿ<EFBFBD><C7B7><EFBFBD>K<EFBFBD><4B>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>Ҫ<EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD>Ľӿڲ<D3BF>һ<EFBFBD><D2BB>
|
||||
|
||||
#define PROTO_VERSION 3
|
||||
#define PROTO_MAGICNUM 0x5641
|
||||
|
||||
/*META_OPT_* same with av_master <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>*/
|
||||
#define META_OPT_LAYER_ADDR 0x52 //META_OPT_LAYER_ADDR
|
||||
#define META_OPT_SINGLE_KEY 0x68
|
||||
#define META_OPT_LAYER_URL 0x61
|
||||
#define META_OPT_ETAG 0x62
|
||||
#define META_OPT_LAST_MODIFY 0x63
|
||||
#define META_OPT_REFERER 0x64 //AV_IdentifyFormatDoc
|
||||
#define META_OPT_USER_AGENT 0x65
|
||||
#define META_OPT_C2S_CONT_TYPE 0x66 //cache and send because of boundary
|
||||
#define META_OPT_S2C_CONT_TYPE 0x67 //cache and send because of boundary
|
||||
#define META_OPT_SERVICE_ID 0x71 /*<2A><>Ƭ<EFBFBD><C6AC>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define META_OPT_C2S_CONT 0x72 /*<2A><>Ƭ<EFBFBD><C6AC>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define META_OPT_S2C_CONT 0x73 /*<2A><>Ƭ<EFBFBD><C6AC>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define META_OPT_CONT_DISPOSITION 0x74 /*<2A><>Ƭ<EFBFBD><C6AC>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define META_OPT_SIP_DIADATA_ID 0x81 /*VOIPʹ<50><CAB9>*/
|
||||
#define META_OPT_SIP_DATA_DIR 0x82
|
||||
#define META_OPT_SIP_RATE_INFO 0x83
|
||||
#define META_OPT_OFFSET 0x69 /*offset<65><74>ѡ<EFBFBD><D1A1>,<2C><>ǰ<EFBFBD><C7B0>һ<EFBFBD><D2BB>*/
|
||||
#define META_OPT_SERVER 0x6A
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>*/
|
||||
#define OPT_SOURCE_IP 0x41 /*localIPѡ<50><D1A1>*/
|
||||
#define META_OPT_SIP_SEND_RATE_INFO 0x71 /*VOIPҵ<50><D2B5>*/
|
||||
|
||||
/*<2A><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD>ƿװ<C6BF><D7B0><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿװ<C6BF><D7B0>ѡ<EFBFBD><D1A1>*/
|
||||
#define META_OPT_INFO_BEFORE_MULTISRC 0x91 /*<2A><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>֮ǰ<D6AE>Ľ<EFBFBD>Ŀ<EFBFBD><C4BF>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MID<49><44>capIP<49><50><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
|
||||
#define FILE_OSMF 0xA1
|
||||
#define FILE_HLS 0xA2
|
||||
#define FILE_IOS 0xA3
|
||||
#define FILE_ANDRIOD 0xA4
|
||||
#define FILE_APP 0xA5
|
||||
#define FILE_FRAG 0xA6 /*<2A><>ƬԤ<C6AC><D4A4>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>url<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>iqiyi*/
|
||||
#define FILE_MAYBE_FRAG 0xA7 /*ǰ<>˻ش<CBBB><D8B4>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ*/
|
||||
#define FILE_AV 0x00 /*<2A><>ƬԤ<C6AC><D4A4>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ0x00*/
|
||||
|
||||
#define VOIP_UNKNOWN_MEDIA_TYPE 0xB0
|
||||
|
||||
/*from papp*/
|
||||
#define MSG_DATA_META 0x31
|
||||
#define MSG_DATA_BODY 0x32
|
||||
#define MSG_DATA_TAIL 0x33
|
||||
|
||||
/*live*/
|
||||
#define MSG_LIVE_CHECK 0x41 //from sapp
|
||||
#define MSG_LIVE_RESPONS 0x42 //to sapp
|
||||
|
||||
/*from av_analyse*/
|
||||
#define MSG_RESP_CHECKRESULT 0x11 // Check Result notification
|
||||
#define MSG_RESP_REJECT 0x12 // Reject Message notification, not proc now
|
||||
#define MSG_RESP_CHARACTER 0x13 // Character notification, 1. wins ack, 2. send to sapp
|
||||
#define MSG_RESP_CHECKRESULT_ACK 0x14 //not send now
|
||||
#define MSG_PROG_SYNC 0x15 //
|
||||
|
||||
/*prog sync*/
|
||||
#define SYNC_SENDER_VIDEO_ANALYZER 0x01
|
||||
#define SYNC_SENDER_AUDIO_ANALYZER 0x02
|
||||
#define SYNC_ACTION_STOP_TO_SUBSYSTEM 0x01
|
||||
#define SYNC_ACTION_STOP_TO_MAINSYSTEM 0x02
|
||||
#define SYNC_ACTION_ELIMINATE_PROGRAM 0x03
|
||||
|
||||
/*<2A><><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD>ܿ<EFBFBD><DCBF><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>*/
|
||||
#define OPT_FRAG_ORIGIN_URL 0x11
|
||||
#define OPT_FRAG_CTRL_SUBSTR 0x12
|
||||
#define OPT_FRAG_INDEX_URL 0x13
|
||||
|
||||
/*FD<46><44><EFBFBD><EFBFBD>: ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>set opt_num=0*/
|
||||
#define SURVEY_PIC_TYPE 0x31
|
||||
#define SURVEY_PIC_MONITOR_TYPE 0xB1
|
||||
#define SURVEY_PIC_KEYWORD_TYPE 0xB2
|
||||
|
||||
// FD<46><44><EFBFBD><EFBFBD>, 0<><30>ʾ<EFBFBD><CABE>̬<EFBFBD>ڰ<EFBFBD><DAB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>ʾ<EFBFBD><CABE>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>2<EFBFBD><32>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>С<EFBFBD>
|
||||
#define FD_TYPE_DYNAMIC_LIST 0
|
||||
#define FD_TYPE_STATIC_CONF 1
|
||||
#define FD_TYPE_ANALYSE 2
|
||||
|
||||
|
||||
/*=================================monitor service===============================================*/
|
||||
|
||||
#define SERVICE_AUDIO_LANG 0x97 //<2F><>ѧ<EFBFBD><D1A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_AUDIO_LANG_FULL 0x98 //<2F><>ƴװ<C6B4><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
|
||||
/*=================================ack msg===============================================*/
|
||||
typedef struct msg_data_ack_s
|
||||
{
|
||||
char prog_id[8];
|
||||
uint16_t pad;
|
||||
uint64_t ack_offset:48;
|
||||
}msg_data_ack_t;
|
||||
|
||||
/*=================================data msg===============================================*/
|
||||
#define MSG_HEADER_LEN sizeof(msg_header_t)
|
||||
typedef struct msg_header_s
|
||||
{
|
||||
uint16_t magic_num;
|
||||
uint8_t version;
|
||||
uint8_t msg_type; // msg data type
|
||||
uint32_t cont_len;
|
||||
}msg_header_t; /* sizeof = 8B */
|
||||
|
||||
#define MSG_MEDIAINFO_HEAD_LEN (sizeof(msg_metainfo_t))
|
||||
/*Data_flag defination*/
|
||||
typedef struct msg_metainfo_s
|
||||
{
|
||||
char prog_id[8];
|
||||
char flag;
|
||||
#if K_PROJECT
|
||||
uint8_t pad[3];
|
||||
int hitservice;
|
||||
uint64_t prog_len;
|
||||
#else
|
||||
uint8_t hitservice;
|
||||
uint64_t prog_len:48;
|
||||
#endif
|
||||
uint32_t cap_IP;
|
||||
uint8_t protocol;
|
||||
uint8_t media_type;
|
||||
uint8_t data_flag;
|
||||
uint8_t opt_num;
|
||||
}msg_metainfo_t;
|
||||
|
||||
typedef struct msg_data_s
|
||||
{
|
||||
char prog_id[8];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t pad;
|
||||
uint8_t flags;
|
||||
};
|
||||
uint16_t frag_seq;
|
||||
};
|
||||
uint64_t offset:48;
|
||||
}msg_data_t;
|
||||
#define MSG_DATA_HEAD_LEN (sizeof(msg_data_t))
|
||||
|
||||
/*==============================response msg==================================================*/
|
||||
typedef struct msg_prog_sync_s
|
||||
{
|
||||
char prog_id[8];
|
||||
uint8_t sender; //0:reserved,1: video analyzer,2:audio analyzer
|
||||
char action; //0:reserved,1:stop send to subsystem,2:stop send to main system,3:eliminate this programm
|
||||
}msg_prog_sync_t;
|
||||
|
||||
#define MSG_RESP_CHECKRESULT_LEN (sizeof(resp_checkresult_t))
|
||||
typedef struct resp_checkresult_s
|
||||
{
|
||||
char prog_id[8];
|
||||
#if K_PROJECT
|
||||
int service;
|
||||
char level; //the level of check result
|
||||
uint8_t opt_num; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>
|
||||
uint8_t pad[6]; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0ֵ
|
||||
#else
|
||||
uint8_t service;
|
||||
char level; //the level of check result
|
||||
uint8_t opt_num; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>
|
||||
uint8_t pad; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0ֵ
|
||||
#endif
|
||||
uint32_t cfg_id; //config ID
|
||||
uint32_t file_header_size;
|
||||
uint32_t file_packet_size;
|
||||
}resp_checkresult_t;
|
||||
|
||||
typedef struct msg_log_s
|
||||
{
|
||||
char prog_id[8]; // program rule id;
|
||||
uint32_t cfg_id; // hitted rule id;
|
||||
uint32_t fount_time; // found time
|
||||
uint32_t server_ip; // server ip;
|
||||
uint32_t client_ip; // client ip;
|
||||
uint16_t server_port; // server port;
|
||||
uint16_t client_port; // client port;
|
||||
uint8_t protocol; // translation protocol num;
|
||||
uint8_t service; // service type;
|
||||
uint8_t level; // result level;
|
||||
uint8_t fd_type; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0<><30>ʾ<EFBFBD><CABE>̬<EFBFBD>ڰ<EFBFBD><DAB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>ʾ<EFBFBD><CABE>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>2<EFBFBD><32>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>С<EFBFBD>
|
||||
}msg_log_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RECV_RESP=0,
|
||||
RECV_RESP_WHITELIST,
|
||||
RESP_MEDIA_NOFOUND,
|
||||
RESP_REPEAT,
|
||||
RESP_AUDIO_LANG_MONITOR_NEW,
|
||||
RESP_AUDIO_LANG_MONITOR_OLD,
|
||||
RESP_SEND_BLOCK,
|
||||
RESP_SEND_BLOCK_MULTI,
|
||||
|
||||
RECV_PROG_SYNC,
|
||||
RECV_PROG_SYNC_NOFOUND,
|
||||
RECV_PROG_SYNC_AUDIO_STOP,
|
||||
RECV_PROG_SYNC_VIDEO_STOP,
|
||||
RECV_PROG_SYNC_UNKNOW,
|
||||
|
||||
SEND_CONFIG_MONITOR,
|
||||
SEND_LANG_MONITOR,
|
||||
}RESP_LOG_TYPE;
|
||||
|
||||
/*VOIP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>ַ<EFBFBD><D6B7>ʽ*/
|
||||
typedef struct layer_addr_v4_s
|
||||
{
|
||||
uint8_t layer_cnt;
|
||||
uint8_t reserved[3];
|
||||
uint32_t client_addr; /* network order, client IP */
|
||||
uint32_t server_addr; /* network order, server IP */
|
||||
uint16_t client_port; /* network order */
|
||||
uint16_t server_port; /* network order */
|
||||
}layer_addr_v4_t;
|
||||
|
||||
void resp_write_to_log(int type, resp_checkresult_t* check_res, void* param1, void* param2, uint64_t param3);
|
||||
|
||||
|
||||
#endif
|
||||
198
src/AV_sendback.h
Normal file
198
src/AV_sendback.h
Normal file
@@ -0,0 +1,198 @@
|
||||
#ifndef _AV_SENDBACK_H
|
||||
#define _AV_SENDBACK_H
|
||||
|
||||
/*ħ<><C4A7>*/
|
||||
#define AV_MAGIC_VALUE 0x8739
|
||||
|
||||
/*<2A><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>*/
|
||||
#define AV_TYPE_META 0x01
|
||||
#define AV_TYPE_DATA 0x02
|
||||
#define AV_TYPE_RESULT 0x11
|
||||
|
||||
/*Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define PROTOCOL_DEFAULT 0x00
|
||||
#define PROTOCOL_HTTP 0x01
|
||||
#define PROTOCOL_SMTP 0x02
|
||||
#define PROTOCOL_POP3 0x03
|
||||
#define PROTOCOL_IMAP 0x04
|
||||
#define PROTOCOL_FTP 0x05
|
||||
#define PROTOCOL_HTTP_PIC 0x06
|
||||
#define PROTOCOL_RTSP_RDT 0x07
|
||||
#define PROTOCOL_RTSP_RTP 0x08
|
||||
#define PROTOCOL_MMS 0x09
|
||||
#define PROTOCOL_RTMP 0x0A
|
||||
#define PROTOCOL_SIP 0x0B
|
||||
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_UNKNOWN 0x00
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>Ƶ֧<C6B5>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_VIDEO 0x01
|
||||
#define MEDIA_TYPE_WMV 0x02
|
||||
#define MEDIA_TYPE_MPG 0x03
|
||||
#define MEDIA_TYPE_FLV 0x04
|
||||
#define MEDIA_TYPE_RMFF 0x05
|
||||
#define MEDIA_TYPE_AVI 0x06
|
||||
#define MEDIA_TYPE_SWF 0x07
|
||||
#define MEDIA_TYPE_MPG4 0x08
|
||||
#define MEDIA_TYPE_AIFF 0x09
|
||||
#define MEDIA_TYPE_OGG 0x0A
|
||||
#define MEDIA_TYPE_DRC 0x0B
|
||||
#define MEDIA_TYPE_DIRECTSHOW 0x0C
|
||||
#define MEDIA_TYPE_FLIC 0x0E
|
||||
#define MEDIA_TYPE_INDEO 0x0F
|
||||
#define MEDIA_TYPE_MKV 0x10
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>Ƶ֧<C6B5>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_AUDIO 0x20
|
||||
#define MEDIA_TYPE_MP3 0x21
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:ͼƬ֧<C6AC>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_IMAGE 0x30
|
||||
#define MEDIA_TYPE_JPG 0x31
|
||||
#define MEDIA_TYPE_BMP 0x32
|
||||
#define MEDIA_TYPE_GIF 0x33
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:ʵʱ<CAB5><CAB1>ý<EFBFBD><C3BD>֧<EFBFBD>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_MMS 0x40
|
||||
#define MEDIA_TYPE_RTSP_RDT 0x41
|
||||
#define MEDIA_TYPE_RTSP_RTP 0x42
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ֧<C6B5>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_OSMF 0x50
|
||||
#define MEDIA_TYPE_HLS 0x51
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:VOIP֧<50>ֵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>༴<EFBFBD><E0BCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_TYPE_AUDIO_UNKNOWN 0x60
|
||||
#define MEDIA_TYPE_AUDIO_G711_ULAW 0x61
|
||||
#define MEDIA_TYPE_AUDIO_G711_ALAW 0x62
|
||||
#define MEDIA_TYPE_AUDIO_G722 0x63
|
||||
#define MEDIA_TYPE_AUDIO_G723 0x64
|
||||
#define MEDIA_TYPE_AUDIO_G726_40 0x65
|
||||
#define MEDIA_TYPE_AUDIO_G726_32 0x66
|
||||
#define MEDIA_TYPE_AUDIO_G726_24 0x67
|
||||
#define MEDIA_TYPE_AUDIO_G726_16 0x68
|
||||
#define MEDIA_TYPE_AUDIO_AAL2_G726_40 0x69
|
||||
#define MEDIA_TYPE_AUDIO_AAL2_G726_32 0x6A
|
||||
#define MEDIA_TYPE_AUDIO_AAL2_G726_24 0x6B
|
||||
#define MEDIA_TYPE_AUDIO_AAL2_G726_16 0x6C
|
||||
#define MEDIA_TYPE_AUDIO_G728 0x6D
|
||||
#define MEDIA_TYPE_AUDIO_G729D 0x6E
|
||||
#define MEDIA_TYPE_AUDIO_G729E 0x6F
|
||||
#define MEDIA_TYPE_AUDIO_GSM 0x70
|
||||
#define MEDIA_TYPE_AUDIO_GSM_EFR 0x71
|
||||
#define MEDIA_TYPE_AUDIO_ILBC 0x72
|
||||
#define MEDIA_TYPE_AUDIO_AMR 0x73
|
||||
#define MEDIA_TYPE_AUDIO_AMR_WB 0x74
|
||||
#define MEDIA_TYPE_AUDIO_SILK 0x75
|
||||
#define MEDIA_TYPE_AUDIO_LPC 0x76
|
||||
#define MEDIA_TYPE_AUDIO_LPC1016 0x77
|
||||
#define MEDIA_TYPE_AUDIO_LPC1015 0x78
|
||||
#define MEDIA_TYPE_AUDIO_L16 0x79
|
||||
#define MEDIA_TYPE_AUDIO_SPEEX 0x7A
|
||||
#define MEDIA_TYPE_AUDIO_L8 0x7B
|
||||
#define MEDIA_TYPE_AUDIO_MPA 0x7C
|
||||
#define MEDIA_TYPE_AUDIO_DVI4 0x7D
|
||||
#define MEDIA_TYPE_AUDIO_VDVI 0x7E
|
||||
#define MEDIA_TYPE_AUDIO_CN 0x7F
|
||||
#define MEDIA_TYPE_AUDIO_RED 0x80
|
||||
#define MEDIA_TYPE_AUDIO_QCELP 0x81
|
||||
#define MEDIA_TYPE_AUDIO_EVRC0 0x82
|
||||
#define MEDIA_TYPE_AUDIO_EVRCB0 0x83
|
||||
#define MEDIA_TYPE_AUDIO_G729 0x84
|
||||
#define MEDIA_TYPE_AUDIO_VIVOX 0x85
|
||||
|
||||
/*ָ<><D6B8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
/*ָ<><D6B8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-VOIPѡ<50><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define OPT_SIP_SEND_RATE_INFO 0x71 /*VOIP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ*/
|
||||
|
||||
/*==================================<3D><>Ϣͷ<CFA2><CDB7>==============================================*/
|
||||
typedef struct msg_head_s
|
||||
{
|
||||
uint16_t magic;
|
||||
uint16_t m_type;
|
||||
uint32_t c_len; //<2F><>Ϣ<EFBFBD>峤<EFBFBD><E5B3A4>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣͷ<CFA2><CDB7>)
|
||||
}msg_head_t;
|
||||
|
||||
/*==================================ָ<><D6B8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>==============================================*/
|
||||
typedef struct msg_meta_s
|
||||
{
|
||||
char pid[8]; //ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint64_t proglen; //<2F><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڳ<D6BD><DAB3>ȣ<EFBFBD>Ϊ0<CEAA><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>δ֪
|
||||
uint32_t capip; // <20><>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>IP
|
||||
uint8_t protocol; // <20><><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t mediatype; // <20><><EFBFBD>ܵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t data_flag; // <20><><EFBFBD>ݱ<EFBFBD>־
|
||||
uint8_t opt_num; // ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}msg_meta_t;
|
||||
|
||||
/*<2A>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>涨<EFBFBD><E6B6A8><EFBFBD><EFBFBD>
|
||||
struct opt_unit_t
|
||||
{
|
||||
uint32_t opt_len; //<2F><><EFBFBD><EFBFBD>opt_len<65><6E>opt_type<70><65>opt_value
|
||||
uint8_t opt_type;
|
||||
char* opt_value;
|
||||
};
|
||||
*/
|
||||
|
||||
/*==================================<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>==============================================*/
|
||||
typedef struct av_data_s
|
||||
{
|
||||
char pid[8]; // <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint16_t frag_seq; // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>Ƭ:Ƭ<><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VOIP:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int64_t offset:48; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>е<EFBFBD>ƫ<EFBFBD><C6AB>λ<EFBFBD><CEBB>
|
||||
//char* avs; // <20><>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}av_data_t;
|
||||
|
||||
/*VOIP<49><50>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ*/
|
||||
struct voip_header_t
|
||||
{
|
||||
uint32_t time_stamp; // <20><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint32_t sequence;
|
||||
//char* data; //VOIP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/*RTSP/RTMP<4D><50>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ*/
|
||||
struct sdp_data_packet
|
||||
{
|
||||
char sdp[8]; // <20><>Ϊ"RTSP_SDP"
|
||||
uint32_t sdp_len; // Ϊsdp<64><70><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
//char * data; // sdp<64><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/*RTSP sdp<64><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ*/
|
||||
struct rtsp_data_packet
|
||||
{
|
||||
uint32_t flag; // RTSP<53><50><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ͷ<EFBFBD><CDB7>־ 0x46464646 "FFFF"
|
||||
uint8_t type; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>1 for RDT<44><54>2 for RTP
|
||||
uint8_t channel; // <20><><EFBFBD>ݵ<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>
|
||||
uint16_t len; // <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
//char * data; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/*RTMP sdp<64><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ*/
|
||||
struct rtmp_data_packet
|
||||
{
|
||||
uint32_t flag; // RTMP<4D><50><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ͷ<EFBFBD><CDB7>־ 0x52544D50"RTMP"
|
||||
uint32_t av_type:8; // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ͣ<EFBFBD>8 for Audio, 9 for Video
|
||||
uint32_t cs_id:24; // Chunk Stream ID
|
||||
uint32_t timestamp; // ʱ<><CAB1><EFBFBD><EFBFBD>
|
||||
uint32_t len; // <20><><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>ֶγ<D6B6><CEB3>ȣ<EFBFBD>20<32>ֽ<EFBFBD>)
|
||||
uint32_t stream_id; // <20><>ID
|
||||
//char * data; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/*MMS<4D><53>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ*/
|
||||
struct mms_data_packet
|
||||
{
|
||||
uint32_t frame_flag; // <20><>Ϊ0x46464646 "FFFF"
|
||||
uint32_t data_len; // Ϊ<><CEAA><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
//char * data; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>D<EFBFBD><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/*==================================<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>==================================================*/
|
||||
typedef struct msg_result_s
|
||||
{
|
||||
char pid[8]; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
int servicetype; // ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint32_t cfgid; // <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ID<49><44>ֵΪ0<CEAA><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>δ֪<CEB4><D6AA><EFBFBD><EFBFBD>
|
||||
int8_t level; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷȣ<C5B6> [0, 100]
|
||||
uint8_t pad[7]; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0ֵ
|
||||
//char* logindex; // <20><><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>Ĵ洢·<E6B4A2><C2B7>URL<52><4C><EFBFBD><EFBFBD>"/0"<22><><EFBFBD><EFBFBD>
|
||||
}msg_result_t;
|
||||
|
||||
#endif
|
||||
233
src/AV_sendback_all.h
Normal file
233
src/AV_sendback_all.h
Normal file
@@ -0,0 +1,233 @@
|
||||
#ifndef _AV_SENDBACK_H
|
||||
#define _AV_SENDBACK_H
|
||||
|
||||
/*ħ<><C4A7>*/
|
||||
#define AV_MAGIC_VALUE 0x8739
|
||||
|
||||
/*<2A><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>*/
|
||||
#define AV_TYPE_META 0x01
|
||||
#define AV_TYPE_DATA 0x02
|
||||
#define AV_TYPE_RESULT 0x11
|
||||
|
||||
/*Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define AV_PROTOCOL_HTTP 0x01
|
||||
#define AV_PROTOCOL_SMTP 0x02
|
||||
#define AV_PROTOCOL_POP3 0x03
|
||||
#define AV_PROTOCOL_FTP 0x04
|
||||
#define AV_PROTOCOL_IMAP 0x05
|
||||
#define AV_PROTOCOL_HTTP_STREAM 0x81
|
||||
#define AV_PROTOCOL_RTSP_RDT 0x82
|
||||
#define AV_PROTOCOL_RTSP_RTP 0x83
|
||||
#define AV_PROTOCOL_ED2K 0x85
|
||||
#define AV_PROTOCOL_MMS 0x84
|
||||
#define AV_PROTOCOL_RTMP 0x86
|
||||
#define AV_PROTOCOL_SIP 0x91
|
||||
#define AV_PROTOCOL_BT 0x08
|
||||
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define FILE_UNKNOWN 0x00
|
||||
#define FILE_VIDEO 0x60
|
||||
#define FILE_WMV 0x61
|
||||
#define FILE_MPG 0x62
|
||||
#define FILE_FLV 0x63
|
||||
#define FILE_RMFF 0x65
|
||||
#define FILE_AVI 0x66
|
||||
#define FILE_SWF 0x67
|
||||
#define FILE_MPG4 0x68
|
||||
#define FILE_AIFF 0x69
|
||||
#define FILE_OGG 0x6A
|
||||
#define FILE_DRC 0x6B
|
||||
#define FILE_DIRECTSHOW 0x6C
|
||||
#define FILE_FLIC 0x6D
|
||||
#define FILE_INDEO 0x6E
|
||||
#define FILE_MKV 0x6F
|
||||
|
||||
#define FILE_AUDIO 0x70
|
||||
#define FILE_MP3 0x71
|
||||
|
||||
#define FILE_OSMF 0xA1
|
||||
#define FILE_HLS 0xA2
|
||||
#define FILE_IOS 0xA3
|
||||
#define FILE_ANDRIOD 0xA4
|
||||
#define FILE_APP 0xA5
|
||||
|
||||
#define AUDIO_UNKNOWN 0xB0
|
||||
#define AUDIO_G711_ULAW 0xB1
|
||||
#define AUDIO_G711_ALAW 0xB2
|
||||
#define AUDIO_G722 0xB3
|
||||
#define AUDIO_G723 0xB4
|
||||
#define AUDIO_G726_40 0xB5
|
||||
#define AUDIO_G726_32 0xB6
|
||||
#define AUDIO_G726_24 0xB7
|
||||
#define AUDIO_G726_16 0xB8
|
||||
#define AUDIO_AAL2_G726_40 0xB9
|
||||
#define AUDIO_AAL2_G726_32 0xBA
|
||||
#define AUDIO_AAL2_G726_24 0xBB
|
||||
#define AUDIO_AAL2_G726_16 0xBC
|
||||
#define AUDIO_G728 0xBD
|
||||
#define AUDIO_G729D 0xBE
|
||||
#define AUDIO_G729E 0xBF
|
||||
#define AUDIO_GSM 0xC0
|
||||
#define AUDIO_GSM_EFR 0xC1
|
||||
#define AUDIO_ILBC 0xC2
|
||||
#define AUDIO_AMR 0xC3
|
||||
#define AUDIO_AMR_WB 0xC4
|
||||
#define AUDIO_SILK 0xC5
|
||||
#define AUDIO_LPC 0xC6
|
||||
#define AUDIO_LPC1016 0xC7
|
||||
#define AUDIO_LPC1015 0xC8
|
||||
#define AUDIO_L16 0xC9
|
||||
#define AUDIO_SPEEX 0xCA
|
||||
#define AUDIO_L8 0xCB
|
||||
#define AUDIO_MPA 0xCC
|
||||
#define AUDIO_DVI4 0xCD
|
||||
#define AUDIO_VDVI 0xCE
|
||||
#define AUDIO_CN 0xCF
|
||||
#define AUDIO_RED 0xD0
|
||||
#define AUDIO_QCELP 0xD1
|
||||
#define AUDIO_EVRC0 0xD2
|
||||
#define AUDIO_EVRCB0 0xD3
|
||||
#define AUDIO_G729 0xD4
|
||||
#define AUDIO_VIVOX 0xD5
|
||||
#define BE_FRAG_TYPE(t) ((t>=FILE_OSMF) && (t<=0xA2))
|
||||
#define BE_APP_TYPE(t) ((t>=FILE_IOS) && (t<=0xA5))
|
||||
#define BE_IMAGE_TYPE(t) ((t>=FILE_IMAGE) && (t<0x90))
|
||||
#define BE_VIDEO_TYPE(t) ((t>=FILE_VIDEO) && (t<0x70))
|
||||
#define BE_AUDIO_TYPE(t) ((t>=FILE_AUDIO) && (t<0x80))
|
||||
#define BE_VOIP_TYPE(t) ((t>=AUDIO_UNKNOWN) && (t<=AUDIO_VIVOX))
|
||||
|
||||
|
||||
#define FILE_IMAGE 0x80
|
||||
|
||||
#define FILE_JPG 0x84
|
||||
#define FILE_BMP 0x85
|
||||
#define FILE_GIF 0x86
|
||||
|
||||
#define MMS_TYPE 0x90
|
||||
#define HTTP_STREAM_TYPE 0x90
|
||||
#define RTSP_RDT_TYPE 0x92
|
||||
#define RTSP_RTP_TYPE 0x91
|
||||
|
||||
/*ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define SERVICE_FLAG_FD 0 // FenDu Flag
|
||||
#define SERVICE_FLAG_JC 1 // JianCe Flag
|
||||
// Defination of service type ;
|
||||
#define SERVICE_IPPORT_WHITE 0x01 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_IPPORT_BLACK 0x02 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_URL_WHITE 0x03 //<2F><>Ŀ<EFBFBD><C4BF>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_URL_BLACK 0x04 //<2F><>Ŀ<EFBFBD><C4BF>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_HOST_WHITE 0x05 //<2F><>Ŀ<EFBFBD><C4BF>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_HOST_BLACK 0x06 //<2F><>Ŀ<EFBFBD><C4BF>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//add by lqy 20120427
|
||||
#define SERVICE_FAKE_SERVERIP 0x07 //<2F><><EFBFBD>ٷ<EFBFBD><D9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||
|
||||
// added by cxj 20100811
|
||||
#define SERVICE_P2P_STATIC_WHITEIP 0x15
|
||||
#define SERVICE_P2P_BI_WHITEIP 0x16
|
||||
#define SERVICE_P2P_MI_WHITEIP 0x17
|
||||
|
||||
#define SERVICE_AUDIO_SAMPLE_FD 0x11
|
||||
#define SERVICE_VIDEO_LABEL_FD 0x21
|
||||
#define SERVICE_SPEEKER_FD 0x22
|
||||
#define SERVICE_VIDEO_SAMPLE_FD 0x23
|
||||
#define SERVICE_VIDEO_FACE_FD 0x24
|
||||
#define SERVICE_AUDIO_SEX_FD 0x25
|
||||
|
||||
#define SERVICE_IMAGE_SAMPLE_FD 0x31
|
||||
#define SERVICE_DYN_SUBSTR_FD 0x32
|
||||
|
||||
|
||||
#define SERVICE_P2P_EMULE_SERVER 0x51 //
|
||||
#define SERVICE_P2P_EMULE_KEY 0x52 //
|
||||
#define SERVICE_P2P_EMULE_FILEID 0x53 //
|
||||
#define SERVICE_P2P_EMULE_NODE 0x54 //
|
||||
|
||||
#define SERVICE_P2P_BT_INFOHASH 0x41 // BT Infohash Black List
|
||||
#define SERVICE_P2P_BT_NODE 0x44 // BT Bone Node
|
||||
#define SERVICE_P2P_BT_SERVICE 0x61 // BT DHT Index Server List
|
||||
|
||||
#define SERVICE_P2P_BT_ECLIPSE_IPLIST 0x45
|
||||
#define SERVICE_P2P_BT_POLLUTION_IPLIST 0x46
|
||||
#define SERVICE_P2P_EMULE_POLLUTION_IPLIST 0x55
|
||||
|
||||
#define SERVICE_P2P_BT_TRACKEIP 0x43 // BT tracke ip
|
||||
#define SERVICE_P2P_BT_PEERIP 0x47 // BT peer ip
|
||||
#define SERVICE_P2P_EMULE_PEERIP 0x56 // emule peer ip
|
||||
|
||||
|
||||
//
|
||||
#define SERVICE_EMULE_SERVER 0x71 //<2F><>ĿΨһID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_EMULE_KEYS 0x72 //<2F><>ĿΨһID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_EMULE_FHID 0x73 //emule<6C><65>hashkey<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_EMULE_FNAME 0x74 //emule<6C><65>hashkey<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_EMULE_NODE 0x75 //emule<6C><65>hashkey<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
#define SERVICE_IPPORT_WHITE_JC 0x81 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_IPPORT_BLACK_JC 0x82 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_URL_WHITE_JC 0x83 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_URL_BLACK_JC 0x84 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_HOST_WHITE_JC 0x85 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_HOST_BLACK_JC 0x86 //IP+PORT<52><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SERVICE_LOAD_ACTION_JC 0x87 /* liuxueli */
|
||||
#define SERVICE_USER_REGION_JC 0x88 /* liuxueli */
|
||||
|
||||
#define SERVICE_AUDIO_SAMPLE_JC 0x91
|
||||
#define SERVICE_SPEEKER_JC 0x92
|
||||
#define SERVICE_AUDIO_CONT_JC 0x93
|
||||
#define SERVICE_AUDIO_SECEN_JC 0x94
|
||||
#define SERVICE_AUDIO_LANG_JC 0x97
|
||||
#define SERVICE_AUDIO_LANG_FULL_JC 0x98
|
||||
|
||||
#define SERVICE_VIDEO_LOGO_JC 0xA1
|
||||
#define SERVICE_VIDEO_SRT_JC 0xA2
|
||||
#define SERVICE_VIDEO_SAMPLE_JC 0xA3
|
||||
#define SERVICE_VIDEO_FACE_JC 0xA4
|
||||
#define SERVICE_VIDEO_SEC_JC 0xA5
|
||||
|
||||
#define SERVICE_IMAGE_SAMPLE_JC 0xB1
|
||||
#define SERVICE_IMAGE_KEYWORD_JC 0xB2
|
||||
#define SERVICE_IMG_FEEDBACK_IP 0xB3
|
||||
#define SERVICE_IMG_FEEDBACK_SIZE 0xB4
|
||||
|
||||
|
||||
/*==================================<3D><>Ϣͷ<CFA2><CDB7>==============================================*/
|
||||
typedef struct msg_header_s
|
||||
{
|
||||
uint16_t magic;
|
||||
uint16_t m_type;
|
||||
uint32_t c_len;
|
||||
}msg_header_t;
|
||||
|
||||
/*==================================ָ<><D6B8><EFBFBD><EFBFBD>Ϣ==============================================*/
|
||||
typedef struct metainfo_s
|
||||
{
|
||||
char pid[8]; //ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint64_t proglen; //<2F><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڳ<D6BD><DAB3>ȣ<EFBFBD>Ϊ0<CEAA><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>δ֪
|
||||
uint32_t capip; // <20><>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>IP
|
||||
uint8_t protocol; // <20><><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t mediatype; // <20><><EFBFBD>ܵ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint16_t pad2; // <20>̶<EFBFBD><CCB6><EFBFBD>0
|
||||
}metainfo_t;
|
||||
|
||||
|
||||
/*==================================<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ==============================================*/
|
||||
typedef struct av_data_s
|
||||
{
|
||||
char pid[8]; // <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint16_t frag_seq; // Ƭ<><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int64_t offset:48; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>е<EFBFBD>ƫ<EFBFBD><C6AB>λ<EFBFBD><CEBB>
|
||||
char* avs; // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}av_data_t;
|
||||
|
||||
/*==================================<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ==================================================*/
|
||||
typedef struct msg_result_s
|
||||
{
|
||||
char pid[8]; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t servicetype; // ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int8_t level; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷȣ<C5B6> [0, 100]
|
||||
uint16_t pad; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0ֵ
|
||||
uint32_t cfgid; // <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ID<49><44>ֵΪ0<CEAA><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>δ֪<CEB4><D6AA><EFBFBD><EFBFBD>
|
||||
char* logindex; //<2F><><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>Ĵ洢·<E6B4A2><C2B7>URL<52><4C><EFBFBD><EFBFBD>"/0"<22><><EFBFBD><EFBFBD>
|
||||
}msg_result_t;
|
||||
|
||||
#endif
|
||||
107
src/AV_sendback_in.h
Normal file
107
src/AV_sendback_in.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef _AV_SENDBACK_IN_H
|
||||
#define _AV_SENDBACK_IN_H
|
||||
|
||||
|
||||
#define AV_MEDAI_TYPE_MAXNUM 128
|
||||
#define AV_PROTO_MAXNUM 16
|
||||
|
||||
/*Э<><D0AD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>ǰ<EFBFBD><C7B0>һ<EFBFBD><D2BB>*/
|
||||
#define AV_PROTOCOL_HTTP 0x01
|
||||
#define AV_PROTOCOL_SMTP 0x02
|
||||
#define AV_PROTOCOL_POP3 0x03
|
||||
#define AV_PROTOCOL_FTP 0x04
|
||||
#define AV_PROTOCOL_IMAP 0x05
|
||||
#define AV_PROTOCOL_HTTP_STREAM 0x81
|
||||
#define AV_PROTOCOL_RTSP_RDT 0x82
|
||||
#define AV_PROTOCOL_RTSP_RTP 0x83
|
||||
#define AV_PROTOCOL_ED2K 0x85
|
||||
#define AV_PROTOCOL_MMS 0x84
|
||||
#define AV_PROTOCOL_RTMP 0x86
|
||||
#define AV_PROTOCOL_SIP 0x91
|
||||
#define AV_PROTOCOL_BT 0x08
|
||||
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>ǰ<EFBFBD><C7B0>һ<EFBFBD><D2BB>*/
|
||||
#define FILE_UNKNOWN 0x00
|
||||
#define FILE_VIDEO 0x60
|
||||
#define FILE_WMV 0x61
|
||||
#define FILE_MPG 0x62
|
||||
#define FILE_FLV 0x63
|
||||
#define FILE_RMFF 0x65
|
||||
#define FILE_AVI 0x66
|
||||
#define FILE_SWF 0x67
|
||||
#define FILE_MPG4 0x68
|
||||
#define FILE_AIFF 0x69
|
||||
#define FILE_OGG 0x6A
|
||||
#define FILE_DRC 0x6B
|
||||
#define FILE_DIRECTSHOW 0x6C
|
||||
#define FILE_FLIC 0x6D
|
||||
#define FILE_INDEO 0x6E
|
||||
#define FILE_MKV 0x6F
|
||||
|
||||
#define FILE_AUDIO 0x70
|
||||
#define FILE_MP3 0x71
|
||||
|
||||
#define FILE_OSMF 0xA1
|
||||
#define FILE_HLS 0xA2
|
||||
#define FILE_IOS 0xA3
|
||||
#define FILE_ANDRIOD 0xA4
|
||||
#define FILE_APP 0xA5
|
||||
|
||||
#define AUDIO_UNKNOWN 0xB0
|
||||
#define AUDIO_G711_ULAW 0xB1
|
||||
#define AUDIO_G711_ALAW 0xB2
|
||||
#define AUDIO_G722 0xB3
|
||||
#define AUDIO_G723 0xB4
|
||||
#define AUDIO_G726_40 0xB5
|
||||
#define AUDIO_G726_32 0xB6
|
||||
#define AUDIO_G726_24 0xB7
|
||||
#define AUDIO_G726_16 0xB8
|
||||
#define AUDIO_AAL2_G726_40 0xB9
|
||||
#define AUDIO_AAL2_G726_32 0xBA
|
||||
#define AUDIO_AAL2_G726_24 0xBB
|
||||
#define AUDIO_AAL2_G726_16 0xBC
|
||||
#define AUDIO_G728 0xBD
|
||||
#define AUDIO_G729D 0xBE
|
||||
#define AUDIO_G729E 0xBF
|
||||
#define AUDIO_GSM 0xC0
|
||||
#define AUDIO_GSM_EFR 0xC1
|
||||
#define AUDIO_ILBC 0xC2
|
||||
#define AUDIO_AMR 0xC3
|
||||
#define AUDIO_AMR_WB 0xC4
|
||||
#define AUDIO_SILK 0xC5
|
||||
#define AUDIO_LPC 0xC6
|
||||
#define AUDIO_LPC1016 0xC7
|
||||
#define AUDIO_LPC1015 0xC8
|
||||
#define AUDIO_L16 0xC9
|
||||
#define AUDIO_SPEEX 0xCA
|
||||
#define AUDIO_L8 0xCB
|
||||
#define AUDIO_MPA 0xCC
|
||||
#define AUDIO_DVI4 0xCD
|
||||
#define AUDIO_VDVI 0xCE
|
||||
#define AUDIO_CN 0xCF
|
||||
#define AUDIO_RED 0xD0
|
||||
#define AUDIO_QCELP 0xD1
|
||||
#define AUDIO_EVRC0 0xD2
|
||||
#define AUDIO_EVRCB0 0xD3
|
||||
#define AUDIO_G729 0xD4
|
||||
#define AUDIO_VIVOX 0xD5
|
||||
|
||||
#define FILE_IMAGE 0x80
|
||||
|
||||
#define FILE_JPG 0x84
|
||||
#define FILE_BMP 0x85
|
||||
#define FILE_GIF 0x86
|
||||
|
||||
#define MMS_TYPE 0x90
|
||||
#define HTTP_STREAM_TYPE 0x90
|
||||
#define RTSP_RDT_TYPE 0x92
|
||||
#define RTSP_RTP_TYPE 0x91
|
||||
|
||||
typedef struct msg_map_s
|
||||
{
|
||||
uint8_t nodeA;
|
||||
uint8_t nodeB;
|
||||
}msg_map_t;
|
||||
|
||||
|
||||
#endif
|
||||
76
src/KafkaProducer.cpp
Normal file
76
src/KafkaProducer.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* KafkaProducer.cpp
|
||||
*
|
||||
* Created on:
|
||||
* Author:
|
||||
*/
|
||||
#include "KafkaProducer.h"
|
||||
|
||||
KafkaProducer::KafkaProducer(const string& b):brokers(b)
|
||||
{
|
||||
partition = RD_KAFKA_PARTITION_UA;
|
||||
};
|
||||
|
||||
int KafkaProducer::KafkaConnection()
|
||||
{
|
||||
config = rd_kafka_conf_new();
|
||||
rd_kafka_conf_set(config, "queue.buffering.max.messages", "1000000", NULL, 0);
|
||||
rd_kafka_conf_set(config, "topic.metadata.refresh.interval.ms", "600000", NULL, 0);
|
||||
|
||||
if (!(kafka = rd_kafka_new(RD_KAFKA_PRODUCER, config, errString, sizeof(errString))))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rd_kafka_brokers_add(kafka, brokers.c_str()) == 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
KafkaProducer::~KafkaProducer()
|
||||
{
|
||||
rd_kafka_destroy(kafka);
|
||||
for(iter = topicHandleMap.begin(); iter!=topicHandleMap.end(); ++iter)
|
||||
{
|
||||
rd_kafka_topic_destroy(iter->second);
|
||||
}
|
||||
rd_kafka_wait_destroyed(5000);
|
||||
}
|
||||
|
||||
rd_kafka_topic_t* KafkaProducer::CreateTopicHandle(const string& topicName)
|
||||
{
|
||||
if(!topicHandleMap.count(topicName))
|
||||
{
|
||||
rd_kafka_topic_conf_t* config = rd_kafka_topic_conf_new();
|
||||
rd_kafka_topic_t* rkt = rd_kafka_topic_new(kafka, topicName.c_str(), config);
|
||||
topicHandleMap[topicName] = rkt;
|
||||
}
|
||||
return topicHandleMap[topicName];
|
||||
}
|
||||
|
||||
int KafkaProducer::SendData(string& topicName, void *payload, size_t paylen)
|
||||
{
|
||||
rd_kafka_topic_t* currentTopicHandle = topicHandleMap[topicName];
|
||||
|
||||
int status = rd_kafka_produce(currentTopicHandle, partition, RD_KAFKA_MSG_F_COPY, payload,
|
||||
paylen, NULL, 0, NULL);
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
int KafkaProducer::MessageInQueue()
|
||||
{
|
||||
return rd_kafka_outq_len(kafka);
|
||||
}
|
||||
|
||||
void KafkaProducer::KafkaPoll(int interval)
|
||||
{
|
||||
rd_kafka_poll(kafka, interval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
54
src/KafkaProducer.h
Normal file
54
src/KafkaProducer.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* kafkaProducer.h
|
||||
*
|
||||
* Created on:
|
||||
* Author:
|
||||
*/
|
||||
|
||||
#ifndef KAFKAPRODUCER_H_
|
||||
#define KAFKAPRODUCER_H_
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "librdkafka/rdkafka.h"
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class KafkaProducer
|
||||
{
|
||||
public:
|
||||
KafkaProducer(const string& b);
|
||||
|
||||
~KafkaProducer();
|
||||
|
||||
int KafkaConnection();
|
||||
|
||||
int SendData(string& topicName, void *payload, size_t paylen);
|
||||
|
||||
int MessageInQueue();
|
||||
|
||||
void KafkaPoll(int interval);
|
||||
rd_kafka_topic_t* CreateTopicHandle(const string& topicName);
|
||||
|
||||
private:
|
||||
int partition;
|
||||
|
||||
string brokers;
|
||||
char errString[512];
|
||||
|
||||
rd_kafka_conf_t* config;
|
||||
rd_kafka_t* kafka;
|
||||
map < string, rd_kafka_topic_t* > topicHandleMap;
|
||||
map < string, rd_kafka_topic_t* >::iterator iter;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* KAFKAPRODUCER_H_ */
|
||||
62
src/Makefile
Normal file
62
src/Makefile
Normal file
@@ -0,0 +1,62 @@
|
||||
vpath %.a ../lib
|
||||
vpath %.h ./inc
|
||||
|
||||
PAPP_PATH=/home/mesasoft/frag_rssb/
|
||||
|
||||
#CFLAGS = -g3 -Wall -fPIC -Werror -O
|
||||
#CFLAGS = -g3 -Wall -fPIC -O
|
||||
INCLUDES = -I./inc/
|
||||
INCLUDES += -I/usr/include/MESA/
|
||||
INCLUDES += -I./support/hiredis-vip-master/
|
||||
CFLAGS = -g3 -Wall -fPIC -D__STDC_FORMAT_MACROS
|
||||
CFLAGS += $(INCLUDES)
|
||||
#LDDICTATOR = -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,realloc
|
||||
LDDICTATOR =
|
||||
CC = g++
|
||||
CCC = g++
|
||||
|
||||
LIB = -L./lib/
|
||||
LIB += -lsoqav_dedup
|
||||
#LIB += -lappdetect
|
||||
LIB += -lrdkafka
|
||||
LIB += -lssl -lcrypto
|
||||
LIB += -lMESA_handle_logger -lMESA_prof_load -lmaatframe -lrulescan -lMESA_htable -lMESA_field_stat2 -lpthread -lasmislog -lwiredcfg -lWiredLB
|
||||
LIB += ./lib/libsifter.a ./lib/libmy_socket.a ./lib/libbusinessman.a ./lib/libMESA_trace.a ./lib/lib_interval_index.a ./lib/lib_MESA_timer.a
|
||||
#LIB += -lhiredis_vip
|
||||
LIB += ./lib/libhiredis_vip.a
|
||||
LIB += ./lib/usm_comm.a
|
||||
#LIB += ./lib/libdictator_debug.a
|
||||
|
||||
LIB_FILE = $(wildcard ../lib/*.a)
|
||||
SOURCES = $(wildcard *.c)
|
||||
SOURCESCPP = $(wildcard *.cpp)
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
OBJECTSCPP = $(SOURCESCPP:.cpp=.o)
|
||||
#DEPS = $(SOURCES:.c=.d)
|
||||
|
||||
|
||||
TARGET = rssb_maskey
|
||||
|
||||
.PHONY:clean all
|
||||
|
||||
all:$(TARGET)
|
||||
|
||||
$(TARGET):$(OBJECTS) $(OBJECTSCPP) $(LIB_FILE)
|
||||
#$(CCC) -shared $(CFLAGS) $(OBJECTS) $(LIB) -o $@
|
||||
$(CCC) $(CFLAGS) $(OBJECTS) $(OBJECTSCPP) $(LIB) $(LDDICTATOR) -o $@
|
||||
cp $(TARGET) ../bin/
|
||||
cp $(TARGET) /home/mesasoft/frag_rssb/
|
||||
|
||||
.c.o:
|
||||
#%.d:%.c
|
||||
# $(CCC) $< -MM $(INCLUDES) > $@
|
||||
|
||||
.cpp.o:
|
||||
#%.dpp:%.cpp
|
||||
$(CCC) $(CFLAGS) -c $<
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
clean :
|
||||
rm -f $(OBJECTS) $(DEPS) $(TARGET)
|
||||
|
||||
393
src/av_record.c
Normal file
393
src/av_record.c
Normal file
@@ -0,0 +1,393 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "stream_fuzzy_hash.h"
|
||||
|
||||
#include "av_record.h"
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
#include "frag_proc.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
|
||||
void free_av_record(av_record_t* av_record)
|
||||
{
|
||||
if(NULL!=av_record->url)
|
||||
{
|
||||
free(av_record->url);
|
||||
}
|
||||
if(NULL!=av_record->referer)
|
||||
{
|
||||
free(av_record->referer);
|
||||
}
|
||||
if(NULL!=av_record->addr)
|
||||
{
|
||||
free(av_record->addr);
|
||||
}
|
||||
free(av_record);
|
||||
}
|
||||
|
||||
int av_record_open_file(int tid)
|
||||
{
|
||||
char str_time[64];
|
||||
time_t currTime;
|
||||
struct tm* now;
|
||||
char filename[MAX_PATH_LEN] = {0};
|
||||
|
||||
time(&currTime);
|
||||
now = localtime(&currTime);
|
||||
strftime(str_time, sizeof(str_time), "%Y-%m-%d-%H-%M-%S", now);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/av_record_capip%u_tid%d_%s", g_frag_cfg.avrecord_filepath, g_frag_cfg.local_ip_nr, tid ,str_time);
|
||||
g_frag_run.av_record_curfile[tid] = fopen(filename,"a+");
|
||||
if(NULL==g_frag_run.av_record_curfile[tid])
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} av_record open filr error: [filename:%s]", __FILE__,__LINE__, filename);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* av_record_thread(void *param)
|
||||
{
|
||||
av_record_t* av_record = NULL;
|
||||
long av_record_len = sizeof(av_record);
|
||||
int rec = 0;
|
||||
long tid = (long)param;
|
||||
|
||||
while(1)
|
||||
{
|
||||
av_record = NULL;
|
||||
rec = MESA_lqueue_get_head(g_frag_run.av_record_lq[tid], &av_record, &av_record_len);
|
||||
if(0!=rec)
|
||||
{
|
||||
usleep(10);
|
||||
continue;
|
||||
}
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[AV_RECORD_QUEUE][QUEUE_OUT]);
|
||||
/*first*/
|
||||
if(NULL==g_frag_run.av_record_curfile[tid])
|
||||
{
|
||||
if(av_record_open_file(tid)<0)
|
||||
{
|
||||
free_av_record(av_record);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*file full*/
|
||||
if(g_frag_run.av_record_curcnt[tid]>=g_frag_cfg.avrecord_maxnum)
|
||||
{
|
||||
fclose(g_frag_run.av_record_curfile[tid]);
|
||||
if(av_record_open_file(tid)<0)
|
||||
{
|
||||
free_av_record(av_record);
|
||||
continue;
|
||||
}
|
||||
g_frag_run.av_record_curcnt[tid] = 0;
|
||||
}
|
||||
/*capip*/
|
||||
char capip4[18] = {0};
|
||||
inet_ntop(AF_INET,(const void *)&av_record->capIP,capip4,18);
|
||||
/*av record write to file*/
|
||||
/*mid*//*media_type*/ /*media_len*/
|
||||
fprintf(g_frag_run.av_record_curfile[tid],"%lu;0x%02x;%lu;%s", av_record->mid,
|
||||
av_record->media_type,
|
||||
av_record->media_len,
|
||||
capip4);
|
||||
/*url*/
|
||||
if(NULL!=av_record->url)
|
||||
{
|
||||
fwrite(";", 1, 1, g_frag_run.av_record_curfile[tid]);
|
||||
fwrite(av_record->url, av_record->url_len, 1, g_frag_run.av_record_curfile[tid]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(g_frag_run.av_record_curfile[tid],";NULL");
|
||||
|
||||
}
|
||||
/*referer*/
|
||||
if(NULL!=av_record->referer)
|
||||
{
|
||||
fwrite(";", 1, 1, g_frag_run.av_record_curfile[tid]);
|
||||
fwrite(av_record->referer, av_record->referer_len, 1, g_frag_run.av_record_curfile[tid]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(g_frag_run.av_record_curfile[tid],";NULL");
|
||||
|
||||
}
|
||||
fwrite("\n", 1, 1, g_frag_run.av_record_curfile[tid]);
|
||||
fflush(g_frag_run.av_record_curfile[tid]);
|
||||
|
||||
g_frag_run.av_record_curcnt[tid]++;
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_AV_RECORD]);
|
||||
free_av_record(av_record);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int av_record(frag_unit_t* frg_unit)
|
||||
{
|
||||
if(g_frag_cfg.avrecord_switch!=AV_RECORD_TYPR_BASIC) return 0;
|
||||
|
||||
av_record_t* av_record = (av_record_t*)calloc(1, sizeof(av_record_t));
|
||||
av_record->mid = frg_unit->mid;
|
||||
av_record->media_len = frg_unit->media_len;
|
||||
av_record->media_type = frg_unit->media_type;
|
||||
av_record->capIP = frg_unit->capIP;
|
||||
|
||||
/*addr*/
|
||||
if(NULL!=frg_unit->opt[MEDIA_OPT_ADDR])
|
||||
{
|
||||
av_record->addr = (char*)malloc(frg_unit->opt[MEDIA_OPT_ADDR]->opt_len);
|
||||
av_record->addr_len = frg_unit->opt[MEDIA_OPT_ADDR]->opt_len;
|
||||
memcpy(av_record->addr, frg_unit->opt[MEDIA_OPT_ADDR]->opt_value, frg_unit->opt[MEDIA_OPT_ADDR]->opt_len);
|
||||
}
|
||||
/*url*/
|
||||
if(NULL!=frg_unit->opt[MEDIA_OPT_URL])
|
||||
{
|
||||
av_record->url = (char*)malloc(frg_unit->opt[MEDIA_OPT_URL]->opt_len);
|
||||
av_record->url_len = frg_unit->opt[MEDIA_OPT_URL]->opt_len;
|
||||
memcpy(av_record->url, frg_unit->opt[MEDIA_OPT_URL]->opt_value, frg_unit->opt[MEDIA_OPT_URL]->opt_len);
|
||||
}
|
||||
/*referer*/
|
||||
if(NULL!=frg_unit->opt[MEDIA_OPT_REFERER])
|
||||
{
|
||||
av_record->referer = (char*)malloc(frg_unit->opt[MEDIA_OPT_REFERER]->opt_len);
|
||||
av_record->referer_len = frg_unit->opt[MEDIA_OPT_REFERER]->opt_len;
|
||||
memcpy(av_record->referer, frg_unit->opt[MEDIA_OPT_REFERER]->opt_value, frg_unit->opt[MEDIA_OPT_REFERER]->opt_len);
|
||||
}
|
||||
MESA_lqueue_join_tail(g_frag_run.av_record_lq[frg_unit->thread_seq], &av_record, sizeof(av_record));
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[AV_RECORD_QUEUE][QUEUE_IN]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void free_av_digest_record(av_digest_record_t* av_digest_record)
|
||||
{
|
||||
if(NULL!=av_digest_record->digest)
|
||||
{
|
||||
free(av_digest_record->digest);
|
||||
}
|
||||
free(av_digest_record);
|
||||
}
|
||||
|
||||
int av_digest_record_open_file(int tid)
|
||||
{
|
||||
char str_time[64];
|
||||
time_t currTime;
|
||||
struct tm* now;
|
||||
char filename[MAX_PATH_LEN] = {0};
|
||||
|
||||
time(&currTime);
|
||||
now = localtime(&currTime);
|
||||
strftime(str_time, sizeof(str_time), "%Y-%m-%d-%H-%M-%S", now);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/av_digest_record_capip%u_tid%d_%s", g_frag_cfg.avrecord_filepath, g_frag_cfg.local_ip_nr, tid, str_time);
|
||||
g_frag_run.av_digest_record_curfile[tid] = fopen(filename,"a+");
|
||||
if(NULL==g_frag_run.av_digest_record_curfile[tid])
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} av_digest_record open filr error: [filename:%s]", __FILE__,__LINE__, filename);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* av_digest_record_thread(void *param)
|
||||
{
|
||||
av_digest_record_t* av_digest_record = NULL;
|
||||
long av_digest_record_len = sizeof(av_digest_record_t);
|
||||
int rec = 0;
|
||||
long tid = (long)param;
|
||||
time_t currTime;
|
||||
struct tm* now;
|
||||
char strTime[32] = {0};
|
||||
char td[TD_LEN] = {0};
|
||||
|
||||
while(1)
|
||||
{
|
||||
av_digest_record = NULL;
|
||||
rec = MESA_lqueue_get_head(g_frag_run.av_digest_record_lq[tid], &av_digest_record, &av_digest_record_len);
|
||||
if(0!=rec)
|
||||
{
|
||||
usleep(10);
|
||||
continue;
|
||||
}
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[AV_DIGEST_RECORD_QUEUE][QUEUE_OUT]);
|
||||
/*first*/
|
||||
if(NULL==g_frag_run.av_digest_record_curfile[tid])
|
||||
{
|
||||
if(av_digest_record_open_file(tid)<0)
|
||||
{
|
||||
free_av_digest_record(av_digest_record);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*file full*/ /*maxnum and path are same with avrecord*/
|
||||
if(g_frag_run.av_digest_record_curcnt[tid]>=g_frag_cfg.avrecord_maxnum)
|
||||
{
|
||||
fclose(g_frag_run.av_digest_record_curfile[tid]);
|
||||
if(av_digest_record_open_file(tid)<0)
|
||||
{
|
||||
free_av_digest_record(av_digest_record);
|
||||
continue;
|
||||
}
|
||||
g_frag_run.av_digest_record_curcnt[tid] = 0;
|
||||
}
|
||||
/*av fuzzy record write to file*/
|
||||
time(&currTime);
|
||||
now = localtime(&currTime);
|
||||
memset(strTime, 0, sizeof(strTime) );
|
||||
strftime(strTime, sizeof(strTime), "%Y-%m-%d %H:%M:%S", now);
|
||||
if(g_frag_cfg.avrecord_switch==AV_RECORD_TYPR_TD)
|
||||
{
|
||||
/*mid*/ /*media_type*/ /*media_len*/
|
||||
fprintf(g_frag_run.av_digest_record_curfile[tid],"%s;%lu;0x%02x;%lu", strTime,
|
||||
av_digest_record->mid,
|
||||
av_digest_record->media_type,
|
||||
av_digest_record->media_len);
|
||||
|
||||
/*td_ori*/
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(av_digest_record->td_ori, av_digest_record->td_ori_len-1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
|
||||
/*td_0k*/
|
||||
caculate_md5(av_digest_record->td_ori, av_digest_record->td_ori_len, NULL, 0, td, TD_LEN);
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(td, strlen(td), 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
|
||||
/*td_data_md5_1k*/ /*td_1k*/
|
||||
/*td_data_md5_2k*/ /*td_2k*/
|
||||
/*td_data_md5_4k*/ /*td_4k*/
|
||||
/*td_data_md5_8k*/ /*td_8k*/
|
||||
/*td_data_md5_16k*/ /*td_16k*/
|
||||
/*td_data_md5_32k*/ /*td_32k*/
|
||||
/*td_data_md5_64k*/ /*td_64k*/
|
||||
int i=0;
|
||||
for(int j=0;j<=6;j++)
|
||||
{
|
||||
i=1<<j;
|
||||
if(av_digest_record->td_data_len>=i*1024)
|
||||
{
|
||||
caculate_md5(NULL, 0, av_digest_record->td_data, i*1024, td, TD_LEN);
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(td, strlen(td), 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
caculate_md5(av_digest_record->td_ori, av_digest_record->td_ori_len, av_digest_record->td_data, i*1024, td, TD_LEN);
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(td, strlen(td), 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*mid*/ /*media_type*/ /*media_len*/ /*digist len*/
|
||||
fprintf(g_frag_run.av_digest_record_curfile[tid],"%s;%lu;0x%02x;%lu", strTime,
|
||||
av_digest_record->mid,
|
||||
av_digest_record->media_type,
|
||||
av_digest_record->media_len);
|
||||
}
|
||||
|
||||
/*digist*/ /*digist len*/
|
||||
fprintf(g_frag_run.av_digest_record_curfile[tid],";%lu",av_digest_record->digest_len);
|
||||
if(NULL!=av_digest_record->digest)
|
||||
{
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(av_digest_record->digest, av_digest_record->digest_len, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(g_frag_run.av_digest_record_curfile[tid],";NULL");
|
||||
}
|
||||
|
||||
/*url*/
|
||||
if(NULL!=av_digest_record->url)
|
||||
{
|
||||
fwrite(";", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fwrite(av_digest_record->url, av_digest_record->url_len, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(g_frag_run.av_digest_record_curfile[tid],";NULL");
|
||||
}
|
||||
|
||||
fwrite("\n", 1, 1, g_frag_run.av_digest_record_curfile[tid]);
|
||||
fflush(g_frag_run.av_digest_record_curfile[tid]);
|
||||
|
||||
g_frag_run.av_digest_record_curcnt[tid]++;
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_AV_DIGEST_RECORD]);
|
||||
free_av_digest_record(av_digest_record);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*record the last url*/
|
||||
int av_digest_record(media_t* mdi)
|
||||
{
|
||||
if(!g_frag_cfg.avrecord_switch) return 0;
|
||||
char* digest_buff = NULL;
|
||||
unsigned long long digest_len = 0;
|
||||
|
||||
if(g_frag_cfg.avrecord_switch==AV_RECORD_TYPR_TD && !mdi->td_complete) return 0;
|
||||
|
||||
av_digest_record_t* av_digest_record = (av_digest_record_t*)calloc(1, sizeof(av_digest_record_t));
|
||||
av_digest_record->mid = mdi->mid;
|
||||
av_digest_record->media_len = mdi->media_len;
|
||||
av_digest_record->media_type = mdi->media_type;
|
||||
|
||||
/*digest*/
|
||||
digest_len = SFH_status(mdi->fuzzy, HASH_LENGTH);
|
||||
digest_buff = (char*)malloc(sizeof(char)*digest_len);
|
||||
av_digest_record->digest_len = SFH_digest(mdi->fuzzy, digest_buff, digest_len);
|
||||
av_digest_record->digest = digest_buff;
|
||||
/*free by av_fuzzy_record_t*/
|
||||
digest_buff = NULL;
|
||||
|
||||
/*td information*/
|
||||
if(g_frag_cfg.avrecord_switch==AV_RECORD_TYPR_TD && mdi->td_complete)
|
||||
{
|
||||
av_digest_record->td_ori_len = mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len;
|
||||
av_digest_record->td_ori = (char*)calloc(1, av_digest_record->td_ori_len);
|
||||
memcpy(av_digest_record->td_ori, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len);
|
||||
|
||||
av_digest_record->td_data_len = mdi->td_datalen;
|
||||
av_digest_record->td_data = (char*)malloc(mdi->td_datalen);
|
||||
memcpy(av_digest_record->td_data, mdi->td_data, mdi->td_datalen);
|
||||
}
|
||||
|
||||
/*url*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
av_digest_record->url = (char*)malloc(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
av_digest_record->url_len = mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
memcpy(av_digest_record->url, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
}
|
||||
|
||||
MESA_lqueue_join_tail(g_frag_run.av_digest_record_lq[mdi->thread_seq], &av_digest_record, sizeof(av_digest_record));
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[AV_DIGEST_RECORD_QUEUE][QUEUE_IN]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
52
src/av_record.h
Normal file
52
src/av_record.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _AV_RECORD_H
|
||||
#define _AV_RECORD_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
#define AV_RECORD_TYPR_BASIC 1 //basic information
|
||||
#define AV_RECORD_TYPR_TD 2 //TD information
|
||||
|
||||
typedef struct av_record_s
|
||||
{
|
||||
uint64_t mid;
|
||||
uint64_t media_len;
|
||||
uint8_t media_type;
|
||||
uint16_t _pad_;
|
||||
uint32_t capIP;
|
||||
char* addr;
|
||||
char* url;
|
||||
char* referer;
|
||||
uint32_t url_len;
|
||||
uint32_t referer_len;
|
||||
uint32_t addr_len; /*IPV4 IPV6*/
|
||||
}av_record_t;
|
||||
|
||||
typedef struct av_digest_record_s
|
||||
{
|
||||
uint64_t mid;
|
||||
uint64_t media_len;
|
||||
uint64_t digest_len;
|
||||
uint64_t td_data_len;
|
||||
char* digest;
|
||||
char* url;
|
||||
char* td_ori; /*<2A><><EFBFBD><EFBFBD>\0*/
|
||||
char* td_data;
|
||||
uint32_t url_len;
|
||||
uint32_t td_ori_len;
|
||||
uint8_t media_type;
|
||||
}av_digest_record_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int av_record(frag_unit_t* frg_unit);
|
||||
int av_digest_record(media_t* mdi);
|
||||
void* av_record_thread(void *param);
|
||||
void* av_digest_record_thread(void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
596
src/cJSON.c
Normal file
596
src/cJSON.c
Normal file
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned parse_hex4(const char *str)
|
||||
{
|
||||
unsigned h=0;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
uc2=parse_hex4(ptr+3);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+4:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void cJSON_Minify(char *json)
|
||||
{
|
||||
char *into=json;
|
||||
while (*json)
|
||||
{
|
||||
if (*json==' ') json++;
|
||||
else if (*json=='\t') json++; // Whitespace characters.
|
||||
else if (*json=='\r') json++;
|
||||
else if (*json=='\n') json++;
|
||||
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
|
||||
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
|
||||
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
|
||||
else *into++=*json++; // All other characters.
|
||||
}
|
||||
*into=0; // and null-terminate.
|
||||
}
|
||||
143
src/cJSON.h
Normal file
143
src/cJSON.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
extern void cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
291
src/common.c
Normal file
291
src/common.c
Normal file
@@ -0,0 +1,291 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "stream.h"
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
|
||||
int pag_send_av_udp(int Datasize, const char *pData, u_int src_ip, u_int dst_ip, u_short src_prt, u_short dst_prt)
|
||||
{
|
||||
printf("empty function,should not be called by preprocesosor!\n");
|
||||
exit(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_pthread(void *(*worker)(void *), void * params, void* logger)
|
||||
{
|
||||
pthread_t thread_desc;
|
||||
pthread_attr_t attr;
|
||||
|
||||
memset(&thread_desc, 0, sizeof(thread_desc));
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
|
||||
if(0 != pthread_attr_init(&(attr)))
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME, "pthread_attr_init(): %d %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_attr_setdetachstate(&(attr), PTHREAD_CREATE_DETACHED))
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME, "pthread_attr_setdetachstate(): %d %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_create(&(thread_desc), &(attr), (void *(*)(void *))(worker), (void *)(params)))
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME, "pthread_create(): %d %s", errno, strerror(errno));
|
||||
pthread_attr_destroy(&(attr));
|
||||
return -1;
|
||||
}
|
||||
pthread_attr_destroy(&(attr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_split (const char* src, char dest[][MAX_PATH_LEN], int dest_maxnum, char sep)
|
||||
{
|
||||
if(NULL==src) return 0;
|
||||
int dest_cnt = 0;
|
||||
const char* start_token = src;
|
||||
const char* end_token = src;
|
||||
const char* end_pos = src+strlen(src);
|
||||
|
||||
while(end_token<end_pos&&dest_cnt<dest_maxnum)
|
||||
{
|
||||
end_token = (char*)memchr(start_token, sep, end_pos-start_token);
|
||||
if(end_token!=NULL)
|
||||
{
|
||||
memcpy(dest[dest_cnt], start_token, end_token-start_token);
|
||||
start_token = end_token+1;
|
||||
end_token += 1;
|
||||
dest_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dest[dest_cnt], start_token, end_pos-start_token);
|
||||
end_token = end_pos;
|
||||
dest_cnt++;
|
||||
}
|
||||
}
|
||||
return dest_cnt;
|
||||
}
|
||||
|
||||
int mkdir_r(const char *path)
|
||||
{
|
||||
int i=0, len=0;
|
||||
int ret=0;
|
||||
len = strlen(path);
|
||||
char dir_path[len+1];
|
||||
dir_path[len] = '\0';
|
||||
|
||||
strncpy(dir_path, path, len);
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (dir_path[i] == '/' && i > 0)
|
||||
{
|
||||
dir_path[i]='\0';
|
||||
if (access(dir_path, F_OK) < 0)
|
||||
{
|
||||
ret=mkdir(dir_path,0755);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("mkdir=%s:msg=%s\n", dir_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
dir_path[i]='/';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//read ip from string like "127.0.1-32;"
|
||||
int MESA_split_read_IP(char *ipstr, int ipnum, unsigned int *output_ip)
|
||||
{
|
||||
char buf[1024] = { 0 };
|
||||
char *begin, *end;
|
||||
int i;
|
||||
int rc = 0;
|
||||
begin = ipstr;
|
||||
end = NULL;
|
||||
for(i = 0; i < ipnum; )
|
||||
{
|
||||
if(NULL != (end = strchr(begin, ';') ) )
|
||||
{
|
||||
memset(buf, 0, 524);
|
||||
strncpy(buf, begin, end - begin);
|
||||
begin = end + 1;
|
||||
char *pchr = strchr(buf, '-');
|
||||
int tmp = 0, tmp2 = 0;
|
||||
if(pchr == NULL)
|
||||
{
|
||||
tmp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ptmp2 = strrchr(buf, '.');
|
||||
tmp2 = atoi(ptmp2 + 1);
|
||||
tmp = atoi(pchr + 1);
|
||||
tmp = tmp - tmp2 + 1;
|
||||
*pchr = '\0';
|
||||
if(tmp <= 0)
|
||||
{
|
||||
printf("MESA_split_read_IP Bad bsendip format %s\n", ipstr);
|
||||
}
|
||||
}
|
||||
rc = inet_addr(buf);
|
||||
if(rc == -1)
|
||||
{
|
||||
printf("MESA_split_read_IP Bad bsendip format %s\n", ipstr);
|
||||
}
|
||||
unsigned int tmpid = ntohl(rc);
|
||||
for(int j = 0; j < tmp; j++)
|
||||
{
|
||||
if(i >= ipnum)
|
||||
{
|
||||
printf("Bad bsendip format,bsendipnum %d not right\n", ipnum);
|
||||
}
|
||||
output_ip[i] = (unsigned int)htonl( (tmpid + j) );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
unsigned int get_ip_by_ifname(const char *ifname)
|
||||
{
|
||||
int sockfd;
|
||||
struct ifreq ifr;
|
||||
unsigned int ip;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (-1 == sockfd)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
strcpy(ifr.ifr_name,ifname);
|
||||
if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
ip = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr;
|
||||
close(sockfd);
|
||||
return ip;
|
||||
|
||||
error:
|
||||
close(sockfd);
|
||||
return INADDR_NONE;
|
||||
}
|
||||
|
||||
/* this function is copy from other system. */
|
||||
/*
|
||||
char *memcasemem(const char *strsrc,int len1,const char *substr,int len2)
|
||||
{
|
||||
|
||||
char *p1,*p2,*pend;
|
||||
char *p;
|
||||
char *substrS;
|
||||
int i,lenth;
|
||||
|
||||
if((strsrc==NULL)||substr==NULL)
|
||||
return NULL;
|
||||
if(len1<len2) return NULL;
|
||||
|
||||
lenth=len2;
|
||||
substrS=(char *)malloc(sizeof(char)*(lenth+1));
|
||||
if(substrS==NULL)
|
||||
return NULL;
|
||||
for(i=0;i<lenth;i++)
|
||||
{
|
||||
substrS[i]=tolower(*(substr+i));
|
||||
}
|
||||
substrS[lenth]=0;
|
||||
|
||||
lenth=len1;
|
||||
pend =(char *)strsrc + lenth;
|
||||
for(p1 =(char *) strsrc; p1 != pend;p1++)
|
||||
{
|
||||
for(p2 = p1,p = substrS;*p != '\0'&& p2 != pend;p++,p2++)
|
||||
{
|
||||
if(tolower(*p2) != *p)
|
||||
break;
|
||||
}
|
||||
if(*p == '\0')
|
||||
{
|
||||
free(substrS);
|
||||
return p1;
|
||||
}
|
||||
}
|
||||
|
||||
free(substrS);
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
/*from sapp*/
|
||||
extern "C" const char *printaddr (const struct layer_addr *paddrinfo, int threadindex)
|
||||
{
|
||||
static char maxbuf[64+1][128];
|
||||
char *buf=maxbuf[threadindex];
|
||||
char ip_str[64];
|
||||
struct stream_tuple4_v4 *paddr;
|
||||
struct stream_tuple4_v6 *paddr6;
|
||||
|
||||
if(NULL == paddrinfo){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
|
||||
{
|
||||
paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
|
||||
memset(buf,0,64);
|
||||
//strcpy (buf, int_ntoa (paddr->saddr));
|
||||
inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
|
||||
strcpy (buf, ip_str);
|
||||
sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
|
||||
//strcat (buf, int_ntoa (paddr->daddr));
|
||||
inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
|
||||
strcat (buf, ip_str);
|
||||
sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
|
||||
}
|
||||
//to addjust
|
||||
else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
|
||||
{
|
||||
paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
|
||||
memset(buf,0,128);
|
||||
inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
|
||||
strcpy (buf, ip_str);
|
||||
sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
|
||||
inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
|
||||
strcat (buf, ip_str);
|
||||
sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (const char *)"Not support layer type";
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
27
src/common.h
Normal file
27
src/common.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#define FRAG_REASSEMBLY_MODULE_NAME "frag_rssb"
|
||||
#define MAX_PATH_LEN 256
|
||||
#define SPLIT_BUF_MAXNUM 8 //config split buf cnt
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int create_pthread(void *(*worker)(void *), void * params, void* logger);
|
||||
int pag_send_av_udp(int Datasize, const char *pData, u_int src_ip, u_int dst_ip, u_short src_prt, u_short dst_prt);
|
||||
int string_split (const char* src, char dest[][MAX_PATH_LEN], int dest_maxnum, char sep);
|
||||
int mkdir_r(const char *path);
|
||||
int MESA_split_read_IP(char *ipstr, int ipnum, unsigned int *output_ip);
|
||||
unsigned int get_ip_by_ifname(const char *ifname);
|
||||
char *memcasemem(const char *strsrc,int len1,const char *substr,int len2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
237
src/frag_app.c
Normal file
237
src/frag_app.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* APP
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
#include "app_detect.h"
|
||||
|
||||
#include "AV_interface.h"
|
||||
|
||||
#include "frag_app.h"
|
||||
#include "frag_proc.h"
|
||||
#include "log.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
extern frag_reassembly_t frag_rssb;
|
||||
|
||||
void app_change_pid(frag_unit_t* frg_unit)
|
||||
{
|
||||
char pid_buf[1024] = {0};
|
||||
char serverIP[64] = {0};
|
||||
uint64_t pid_before = frg_unit->pid;
|
||||
/*APP<50><50>PID<49><EFBFBD>ΪserverIP+len, <20><><EFBFBD><EFBFBD>tuple7*/
|
||||
get_serverIP(frg_unit->opt[MEDIA_OPT_ADDR]->opt_value, frg_unit->opt[MEDIA_OPT_ADDR]->opt_len, serverIP);
|
||||
snprintf(pid_buf, sizeof(pid_buf), "APP_%s->%" PRIu64 "", serverIP, frg_unit->content_length);
|
||||
frg_unit->pid = make_mid(pid_buf, strlen(pid_buf), PID_TYPE_IPLEN);
|
||||
frg_unit->mid = frg_unit->pid;
|
||||
frag_write_to_log(APP_CHANGE_PID, pid_before, frg_unit, NULL, 0);
|
||||
}
|
||||
|
||||
static int url_indicated_app(const char *url)
|
||||
{
|
||||
const char *pfilename = NULL, *p1 = NULL, *p2 = NULL, *p3 = NULL, *p = NULL;
|
||||
unsigned int len=0;
|
||||
|
||||
if(url == NULL)
|
||||
return 0;
|
||||
|
||||
pfilename = strrchr(url, '/');
|
||||
if(pfilename == NULL || *(pfilename + 1) == '\0')
|
||||
return 0;
|
||||
|
||||
pfilename = pfilename + 1;
|
||||
len = strlen(pfilename);
|
||||
|
||||
p1 = strchr(pfilename, ';');
|
||||
p2 = strchr(pfilename, '?');
|
||||
p3 = strchr(pfilename, '#');
|
||||
|
||||
if(p1>p2)
|
||||
{
|
||||
p = p1; p1 = p2; p2 = p;
|
||||
}
|
||||
if(p1>p3)
|
||||
{
|
||||
p = p3; p1 = p3; p3 = p;
|
||||
}
|
||||
if(p2>p3)
|
||||
{
|
||||
p = p2; p2 = p3; p3 = p;
|
||||
}
|
||||
if(p1 != NULL)
|
||||
len = p1 - pfilename;
|
||||
else if(p2 != NULL)
|
||||
len = p2 - pfilename;
|
||||
else if(p3 != NULL)
|
||||
len = p3 - pfilename;
|
||||
|
||||
if(!strncasecmp(pfilename + len - 4, ".apk", 4))
|
||||
return FILE_ANDRIOD;
|
||||
if(!strncasecmp(pfilename + len - 4, ".ipa", 4))
|
||||
return FILE_IOS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_appdtc_detail(appdtc_detail_in_t* detail)
|
||||
{
|
||||
if(NULL!=detail)
|
||||
{
|
||||
if(NULL!=detail->app_data)
|
||||
{
|
||||
free(detail->app_data);
|
||||
}
|
||||
if(NULL!=detail->tuple4)
|
||||
{
|
||||
free(detail->tuple4);
|
||||
}
|
||||
if(NULL!=detail->url)
|
||||
{
|
||||
free(detail->url);
|
||||
}
|
||||
if(NULL!=detail->user_agent)
|
||||
{
|
||||
free(detail->user_agent);
|
||||
}
|
||||
if(NULL!=detail->app_frg_lq)
|
||||
{
|
||||
MESA_lqueue_destroy(detail->app_frg_lq, NULL, NULL);
|
||||
detail->app_frg_lq = NULL;
|
||||
}
|
||||
free(detail);
|
||||
}
|
||||
}
|
||||
|
||||
void proc_app_data(media_t* mdi)
|
||||
{
|
||||
appdtc_detail_in_t* detail = (appdtc_detail_in_t*)calloc(1, sizeof(appdtc_detail_in_t));
|
||||
char* p_url = NULL;
|
||||
|
||||
/*appid*/
|
||||
detail->appid = mdi->mid;
|
||||
|
||||
/*app_type*/
|
||||
if(mdi->media_type==FILE_APP)
|
||||
{
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
p_url = (char*)malloc(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len+1);
|
||||
memset(p_url, 0 , mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len+1);
|
||||
memcpy(p_url, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
mdi->media_type = url_indicated_app(p_url);
|
||||
if(NULL!=p_url)
|
||||
{
|
||||
free(p_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(mdi->media_type)
|
||||
{
|
||||
case FILE_IOS:
|
||||
detail->app_type = APP_TYPE_IOS;
|
||||
break;
|
||||
case FILE_ANDRIOD:
|
||||
detail->app_type = APP_TYPE_ANDROID;
|
||||
break;
|
||||
default:
|
||||
detail->app_type = APP_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
/*data*/
|
||||
detail->app_frg_lq = mdi->app_frg_lq;
|
||||
mdi->app_frg_lq = NULL;
|
||||
|
||||
/*tuple4*/
|
||||
if(NULL!=mdi->addrlist)
|
||||
{
|
||||
detail->tuple4 = (char*)malloc(mdi->addrlist_len);
|
||||
memcpy(detail->tuple4, mdi->addrlist, mdi->addrlist_len);
|
||||
detail->tuple4_len = mdi->addrlist_len;
|
||||
}
|
||||
|
||||
/*url : app_http_session urls are same, so save one*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
detail->url = (char*)malloc(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
memcpy(detail->url, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
detail->url_len = mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
|
||||
/*ua*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index])
|
||||
{
|
||||
detail->user_agent = (char*)malloc(mdi->opt[MEDIA_OPT_UA][mdi->url_opt_index]->opt_len);
|
||||
memcpy(detail->user_agent, mdi->opt[MEDIA_OPT_UA][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_UA][mdi->url_opt_index]->opt_len);
|
||||
detail->ua_len = mdi->opt[MEDIA_OPT_UA][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[APP_QUEUE][QUEUE_IN]);
|
||||
MESA_lqueue_join_tail(g_frag_run.app_lq, &detail, sizeof(detail));
|
||||
}
|
||||
|
||||
void* thread_send_app_data(void *param)
|
||||
{
|
||||
appdtc_detail_in_t* detail = NULL;
|
||||
long detail_len = sizeof(detail);
|
||||
frag_in_t* frg = NULL;
|
||||
long frglen = sizeof(frg);
|
||||
int rec_detail = 0;
|
||||
int rec_frg = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rec_detail = MESA_lqueue_try_get_head(g_frag_run.app_lq, &detail, &detail_len);
|
||||
if (rec_detail<0)
|
||||
{
|
||||
usleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
rec_frg = MESA_lqueue_try_get_head(detail->app_frg_lq, &frg, &frglen);
|
||||
while(0==rec_frg)
|
||||
{
|
||||
atomic_inc(&frag_rssb.sysinfo_stat[RSSB_WAIT_QUEUE][QUEUE_OUT]);
|
||||
MESA_handle_runtime_log(frag_rssb.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} get app_frg_lq: [PID: %llu, offset: %llu, datalen:%u]",
|
||||
__FILE__,__LINE__, frg->pid, frg->offset, frg->datalen);
|
||||
if(detail->data_len > frg->offset+frg->datalen)
|
||||
{
|
||||
memcpy((char*)detail->app_data+frg->offset, (void*)frg->data, frg->datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail->app_data = (char*)realloc(detail->app_data, frg->offset+frg->datalen);
|
||||
memcpy((char*)detail->app_data+frg->offset, (void*)frg->data, frg->datalen);
|
||||
detail->data_len = frg->offset+frg->datalen;
|
||||
}
|
||||
free_frag_in(frg,0,NULL);
|
||||
rec_frg = MESA_lqueue_try_get_head(detail->app_frg_lq, &frg, &frglen);
|
||||
}
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[APP_QUEUE][QUEUE_OUT]);
|
||||
atomic_inc(&g_frag_stat.stat_info[TO_SEND][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[TO_SEND][TOTAL_BYTES], detail->data_len);
|
||||
#if APP_FUNC
|
||||
APPDTC_PLUG_ENTRY(g_frag_run.appdtc_handle, (appdtc_detail_t*)detail, 0);
|
||||
#endif
|
||||
free_appdtc_detail(detail);
|
||||
detail = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
34
src/frag_app.h
Normal file
34
src/frag_app.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef _FRAG_APP_H
|
||||
#define _FRAG_APP_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
typedef struct __appdtc_detail_in_s
|
||||
{
|
||||
char *tuple4;
|
||||
char *user_agent;
|
||||
char *url;
|
||||
void *app_data;
|
||||
unsigned int tuple4_len;
|
||||
unsigned short app_type; //APP_TYPE_t
|
||||
unsigned int ua_len;
|
||||
unsigned int url_len;
|
||||
unsigned long long data_len;
|
||||
unsigned long long appid;
|
||||
MESA_lqueue_head app_frg_lq; //app<70><70><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
||||
}appdtc_detail_in_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void app_change_pid(frag_unit_t* frg_unit);
|
||||
void proc_app_data(media_t* mdi);
|
||||
void* thread_send_app_data(void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
1510
src/frag_av.c
Normal file
1510
src/frag_av.c
Normal file
File diff suppressed because it is too large
Load Diff
35
src/frag_av.h
Normal file
35
src/frag_av.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _FRAG_AV_H
|
||||
#define _FRAG_AV_H
|
||||
|
||||
#define MAAT_RESULT_NUM 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void frag_set_offset(uint8_t media_type, frag_in_t* frg, frag_unit_t* frg_unit);
|
||||
int frag_redis_index_twice(frag_unit_t* frg_unit);
|
||||
|
||||
long converge_mediainfo_search_cb(void *data, const uint8_t *key, uint size, void *user_arg);
|
||||
int expire_cnvg_hash_node(void *data, int eliminate_type);
|
||||
void set_frag_unit(rssb_media_info_t* media_info, frag_unit_t* frg_unit);
|
||||
void proc_index_queue(frag_unit_t* frg_unit);
|
||||
|
||||
int is_frag(uint8_t media_type);
|
||||
void media_stat(media_t* mdi, frag_unit_t* frg_unit);
|
||||
void media_byte_stat(media_t* mdi, frag_unit_t* frg_unit, frag_in_t* frg);
|
||||
int media_frag_removal(media_t* mdi, frag_unit_t* frg_unit);
|
||||
int media_removal(media_t* mdi, frag_unit_t* frg_unit, frag_in_t* frg, frag_ivi_info_t* frag_ivi_info);
|
||||
|
||||
int av_query(frag_unit_t* frg_unit);
|
||||
int redis_av_query(frag_unit_t* frg_unit);
|
||||
void index_query_timeout_free(void * context);
|
||||
void index_query_timeout(void * context);
|
||||
long index_query_timeout_cb(void *data, const uint8_t *key, uint size, void *user_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
514
src/frag_dedup.c
Normal file
514
src/frag_dedup.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>ѯҵ<D1AF><D2B5>
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "MESA_htable.h"
|
||||
#include "MESA_list_queue.h"
|
||||
#include "stream_fuzzy_hash.h"
|
||||
#include "soqav_dedup.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
#include "frag_proc.h"
|
||||
#include "frag_dedup.h"
|
||||
#include "frag_av.h"
|
||||
#include "log.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
|
||||
uchar addrlist_to_streamtuple4(const char *addr, struct stream_tuple4_v4 *tuple4_v4, struct stream_tuple4_v6 *tuple4_v6)
|
||||
{
|
||||
uchar addrtype = 0;
|
||||
|
||||
touple4_type_t touple4;
|
||||
|
||||
if(sscanf(addr, "%[0-9.],%hu>%[0-9.],%hu", touple4.sip, &touple4.sport, touple4.dip, &touple4.dport) == 4)
|
||||
{
|
||||
addrtype = ADDR_TYPE_IPV4;
|
||||
inet_pton(AF_INET, touple4.sip, &tuple4_v4->saddr);
|
||||
inet_pton(AF_INET, touple4.dip, &tuple4_v4->daddr);
|
||||
tuple4_v4->source = htons(touple4.sport);
|
||||
tuple4_v4->dest = htons(touple4.dport);
|
||||
}
|
||||
else if(sscanf(addr, "%[0-9A-Fa-f:.],%hu>%[0-9A-Fa-f:.],%hu", touple4.sip, &touple4.sport, touple4.dip, &touple4.dport) == 4)
|
||||
{
|
||||
addrtype = ADDR_TYPE_IPV6;
|
||||
inet_pton(AF_INET6, touple4.sip, tuple4_v6->saddr);
|
||||
inet_pton(AF_INET6, touple4.dip, tuple4_v6->daddr);
|
||||
tuple4_v6->source = htons(touple4.sport);
|
||||
tuple4_v6->dest = htons(touple4.dport);
|
||||
}
|
||||
return addrtype;
|
||||
}
|
||||
|
||||
void media_dedup_report(media_t* mdi)
|
||||
{
|
||||
char* digest_buff = NULL;
|
||||
unsigned long long digest_len = 0;
|
||||
report_detail_t detail;
|
||||
struct stream_tuple4_v4 tuple4_v4;
|
||||
struct stream_tuple4_v6 tuple4_v6;
|
||||
|
||||
memset(&detail, 0, sizeof(report_detail_t));
|
||||
|
||||
if(mdi->configID)
|
||||
{
|
||||
detail.scan_detail = (scan_detail_t*)malloc(sizeof(scan_detail_t));
|
||||
detail.scan_detail->config_id = mdi->configID;
|
||||
}
|
||||
|
||||
detail.mid = mdi->mid;
|
||||
detail.current_len = mdi->byte_proc;
|
||||
detail.total_len = mdi->media_len;
|
||||
detail.ivi_handle = mdi->ivi;
|
||||
|
||||
/*digest*/
|
||||
if(NULL!=mdi->fuzzy)
|
||||
{
|
||||
digest_len = SFH_status(mdi->fuzzy, HASH_LENGTH);
|
||||
digest_buff = (char*)malloc(sizeof(char)*digest_len);
|
||||
detail.sfh_len = SFH_digest(mdi->fuzzy, digest_buff, digest_len);
|
||||
detail.file_sfh = digest_buff;
|
||||
}
|
||||
|
||||
/*url*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
detail.urllen = mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
detail.url = mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value;
|
||||
}
|
||||
|
||||
/*addr*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index])
|
||||
{
|
||||
detail.addrtype = addrlist_to_streamtuple4(mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index]->opt_value, &tuple4_v4, &tuple4_v6);
|
||||
switch(detail.addrtype)
|
||||
{
|
||||
case ADDR_TYPE_IPV4:
|
||||
detail.tuple4_v4 = &tuple4_v4;
|
||||
break;
|
||||
case ADDR_TYPE_IPV6:
|
||||
detail.tuple4_v6 = &tuple4_v6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_DEDUP) && !FLAG_TEST(mdi->td_query, TD_QUERY_RES_NOREPORT))
|
||||
{
|
||||
soqav_dedup_report(g_frag_run.dedup_hd, mdi->td, &detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*<2A>ظ<EFBFBD><D8B8><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>Ҫ<EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD>TD<54><44>ΪNULL*/
|
||||
soqav_dedup_report(g_frag_run.dedup_hd, NULL, &detail);
|
||||
}
|
||||
frag_write_to_log(AV_DEDUP_REPORT, mdi->mid, (void*)mdi->td, (void*)&mdi->byte_proc, mdi->configID);
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_REPORT]);
|
||||
if(mdi->td_complete)
|
||||
{
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_REPORT_COMPLETE]);
|
||||
}
|
||||
|
||||
if(NULL!=digest_buff)
|
||||
{
|
||||
free(digest_buff);
|
||||
}
|
||||
if(NULL!=detail.scan_detail)
|
||||
{
|
||||
free(detail.scan_detail);
|
||||
}
|
||||
}
|
||||
|
||||
long media_query_ack(void *data, const uint8_t *key, uint size, void *user_arg)
|
||||
{
|
||||
media_t* mdi = (media_t*)data;
|
||||
char ip_buf[64] = {0};
|
||||
query_result_t* ack_rsl = (query_result_t*)user_arg;
|
||||
int result = ack_rsl->status;
|
||||
uint32_t multisrc_bizmanip = ack_rsl->cpz_payload_ip;
|
||||
|
||||
/*<2A><><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD>*/
|
||||
/*
|
||||
result = BIT_TD_MULTI_SOURCE;
|
||||
multisrc_bizmanip = 16777343;
|
||||
ack_rsl->mid = 1111283823269670000;
|
||||
*/
|
||||
|
||||
if(NULL!=mdi)
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD>֮ǰ<D6AE>յ<EFBFBD><D5B5><EFBFBD>Ӧ<EFBFBD>𣬲<EFBFBD><F0A3ACB2><EFBFBD><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>*/
|
||||
if(FLAG_TEST(mdi->td_query, TD_QUERY_ACK_DEDUP) || FLAG_TEST(mdi->td_query, TD_QUERY_ACK_MULTISRC))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_ACK_DEDUP);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_ACK_MULTISRC);
|
||||
|
||||
/*debug <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>debugģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧЧ*/
|
||||
/*<2A><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>*/
|
||||
if(FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_MULTISRC))
|
||||
{
|
||||
if(result & BIT_TD_KNOWN)
|
||||
{
|
||||
frag_write_to_log(RECV_AV_DEDUP_ACK_KNOWN, mdi->mid, (void*)mdi->td, &result, 0);
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP]);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_RES_DEDUP);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_RES_NOREPORT);
|
||||
}
|
||||
/*<2A><><EFBFBD><EFBFBD>IP<49>DZ<EFBFBD><C7B1><EFBFBD>16777343(127.0.0.1)<29><><EFBFBD>ҽ<EFBFBD>ĿIDһ<44><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ۺ<EFBFBD>*/
|
||||
else if(result & BIT_TD_MULTI_SOURCE && (multisrc_bizmanip!=16777343 ||(multisrc_bizmanip==16777343 && mdi->mid != (uint64_t)ack_rsl->mid)))
|
||||
{
|
||||
inet_ntop(AF_INET, &multisrc_bizmanip, ip_buf, 64);
|
||||
frag_write_to_log(RECV_AV_DEDUP_ACK_MULTI, mdi->mid, mdi, ip_buf, 0);
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_MULTI]);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_RES_MULTISRC);
|
||||
mdi->mid_after_multisrc = ack_rsl->mid;
|
||||
mdi->multisrc_bizmanip = multisrc_bizmanip;
|
||||
create_media_write_to_log(mdi, MEDIA_MID_CHANGE, &ack_rsl->mid);
|
||||
}
|
||||
|
||||
struct queue_item* first_item = TAILQ_FIRST(&mdi->query_wait_lq);
|
||||
frag_ivi_info_t frag_ivi_info;
|
||||
while(first_item != NULL)
|
||||
{
|
||||
memset(&frag_ivi_info, 0, sizeof(frag_ivi_info));
|
||||
struct queue_item *item = TAILQ_NEXT(first_item, entries);
|
||||
TAILQ_REMOVE(&mdi->query_wait_lq, first_item, entries);
|
||||
frag_ivi_info.frg = (frag_in_t*)first_item->node;
|
||||
frag_ivi_info.thread_seq = first_item->thread_seq;
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[MULTISRC_QUEUE][QUEUE_OUT]);
|
||||
frag_write_to_log(ADD_FRAG_FROM_TAILQ, frag_ivi_info.frg->mid, frag_ivi_info.frg, NULL, 0);
|
||||
/*<2A><>Ŀ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>ֱ<EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>*/
|
||||
if(result & BIT_TD_KNOWN && !g_frag_cfg.dedup_invalid)
|
||||
{
|
||||
/*<2A><>Ӧ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD>ȥ<EFBFBD><C8A5>ͳ<EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>Ϊ<EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><CDB8>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
free_frag_in(frag_ivi_info.frg,0,NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(result & BIT_TD_MULTI_SOURCE && (multisrc_bizmanip!=16777343 ||(multisrc_bizmanip==16777343 && mdi->mid != (uint64_t)ack_rsl->mid)))
|
||||
{
|
||||
frag_ivi_info.frg->new_mid = mdi->mid_after_multisrc;
|
||||
frag_ivi_info.frg->multisrc_bizmanip = mdi->multisrc_bizmanip;
|
||||
FLAG_SET(frag_ivi_info.frg->frag_flag, FRAG_FLAG_MULTISRC);
|
||||
frag_add_wait_lq(&frag_ivi_info, 1, frag_ivi_info.thread_seq);
|
||||
}
|
||||
/*<2A><><EFBFBD>ۺϵĶ<CFB5>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><CDB9><EFBFBD>*/
|
||||
else
|
||||
{
|
||||
free_frag_in(frag_ivi_info.frg,0,NULL);
|
||||
}
|
||||
}
|
||||
free(first_item);
|
||||
first_item = NULL;
|
||||
first_item = item;
|
||||
}
|
||||
}
|
||||
else if(result & BIT_TD_KNOWN)
|
||||
{
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP]);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_RES_DEDUP);
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_RES_NOREPORT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_TIMEOUT]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long soqav_query_callback(const char *td, const query_result_t *result, void *user_arg)
|
||||
{
|
||||
long rec_cb = 0;
|
||||
uint64_t media_mid = (uint64_t)user_arg;
|
||||
|
||||
frag_write_to_log(RECV_AV_DEDUP_ACK, media_mid, (void*)td, (void*)&result->status, 0);
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t *)&media_mid, sizeof(media_mid),
|
||||
media_query_ack, (void*)result, &rec_cb);
|
||||
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_ACK]);
|
||||
return rec_cb;
|
||||
}
|
||||
|
||||
void generate_td_meta(media_t* mdi)
|
||||
{
|
||||
char* td_buf = NULL;
|
||||
int td_buflen = 0;
|
||||
char media_len[64] = {0};
|
||||
char media_type[16] = {0};
|
||||
char serverIP[64] = {0};
|
||||
|
||||
snprintf(media_type, sizeof(media_type), "%hhu", mdi->media_type);
|
||||
if(is_frag(mdi->media_type))
|
||||
{
|
||||
snprintf(media_len, sizeof(media_len), "%lu", mdi->media_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(media_len, sizeof(media_len), "%d", 0);
|
||||
}
|
||||
|
||||
if(mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
get_serverIP(mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index]->opt_len, serverIP);
|
||||
}
|
||||
|
||||
td_buflen = strlen("URL:")
|
||||
+strlen("ServerIP:")+strlen(serverIP)
|
||||
+strlen("MediaType:")+strlen(media_type)
|
||||
+strlen("MediaLen:")+strlen(media_len)
|
||||
+strlen("Etag:")
|
||||
+strlen("LastModify:")
|
||||
+1;
|
||||
if(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
td_buflen+=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
if(mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
td_buflen+=mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
if(mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index] !=NULL)
|
||||
{
|
||||
td_buflen+=mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
td_buf = (char*)calloc(1, td_buflen);
|
||||
char* p_td_buf = td_buf;
|
||||
|
||||
memcpy(p_td_buf, "URL:" ,strlen("URL:"));
|
||||
p_td_buf += strlen("URL:");
|
||||
if(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
memcpy(p_td_buf,mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value,mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
p_td_buf += mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
memcpy(p_td_buf, "ServerIP:" ,strlen("ServerIP:"));
|
||||
p_td_buf += strlen("ServerIP:");
|
||||
if(strlen(serverIP) >0)
|
||||
{
|
||||
memcpy(p_td_buf, serverIP,strlen(serverIP));
|
||||
p_td_buf += strlen(serverIP);
|
||||
}
|
||||
memcpy(p_td_buf, "MediaType:" ,strlen("MediaType:"));
|
||||
p_td_buf += strlen("MediaType:");
|
||||
memcpy(p_td_buf, media_type, strlen(media_type));
|
||||
p_td_buf += strlen(media_type);
|
||||
memcpy(p_td_buf, "MediaLen:" ,strlen("MediaLen:"));
|
||||
p_td_buf += strlen("MediaLen:");
|
||||
memcpy(p_td_buf, media_len, strlen(media_len));
|
||||
p_td_buf += strlen(media_len);
|
||||
|
||||
memcpy(p_td_buf, "Etag:" ,strlen("Etag:"));
|
||||
p_td_buf += strlen("Etag:");
|
||||
if(mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
memcpy(p_td_buf, mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index]->opt_value,mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index]->opt_len);
|
||||
p_td_buf += mdi->opt[MEDIA_OPT_ETAG][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
memcpy(p_td_buf, "LastModify:" ,strlen("LastModify:"));
|
||||
p_td_buf += strlen("LastModify:");
|
||||
if(mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index] != NULL)
|
||||
{
|
||||
memcpy(p_td_buf, mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index]->opt_len);
|
||||
p_td_buf += mdi->opt[MEDIA_OPT_LAST_MODIFY][mdi->url_opt_index]->opt_len;
|
||||
}
|
||||
|
||||
mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index] = (opt_in_t*)malloc(sizeof(opt_in_t));
|
||||
mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len = td_buflen;
|
||||
mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_type = 0;
|
||||
mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value = (char*)malloc(td_buflen);
|
||||
memcpy(mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value,td_buf,td_buflen);
|
||||
if(NULL!=td_buf)
|
||||
{
|
||||
free(td_buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
long set_td_data(media_t* mdi, frag_in_t* frg)
|
||||
{
|
||||
uint64_t cur_td_datalen = 0;
|
||||
|
||||
if(mdi->td_complete==0 && frg->offset<g_frag_cfg.td_data_maxsize)
|
||||
{
|
||||
if(NULL==mdi->td_data)
|
||||
{
|
||||
mdi->td_data = (char*)malloc(g_frag_cfg.td_data_maxsize);
|
||||
}
|
||||
if(NULL!=mdi->td_data)
|
||||
{
|
||||
cur_td_datalen = ((frg->offset+frg->datalen)>g_frag_cfg.td_data_maxsize) ? (g_frag_cfg.td_data_maxsize-frg->offset): frg->datalen;
|
||||
memcpy(mdi->td_data+frg->offset, frg->data, cur_td_datalen);
|
||||
mdi->td_datalen += cur_td_datalen;
|
||||
/*td_data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>ѯ*/
|
||||
if(mdi->td_datalen==g_frag_cfg.td_data_maxsize)
|
||||
{
|
||||
//url is not empty,<2C>ȴ<EFBFBD><C8B4><EFBFBD>Դ<EFBFBD><D4B4>ѯURL<52><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>url<72><6C><EFBFBD><EFBFBD>TD
|
||||
if(NULL != mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
FLAG_SET(mdi->td_query,TD_QUERY_TYPE_DEDUP);
|
||||
generate_td_meta(mdi);
|
||||
caculate_md5(mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len, mdi->td_data, mdi->td_datalen, mdi->td, TD_LEN);
|
||||
mdi->td_complete = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void soqav_query_timeout(void * context)
|
||||
{
|
||||
struct timer_context_t *ctx = (struct timer_context_t *)context;
|
||||
uint64_t mid = ctx->mid;
|
||||
long rec_cb = 0;
|
||||
|
||||
query_result_t result;
|
||||
|
||||
result.status = 0;
|
||||
result.cpz_mg_ip = 0;
|
||||
result.cpz_payload_ip = 0;
|
||||
result.reserve = 0;
|
||||
result.mid = mid;
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_ACK_TIMEOUT]);
|
||||
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t *)&mid, sizeof(mid),
|
||||
media_query_ack, &result, &rec_cb);
|
||||
}
|
||||
|
||||
void soqav_query_free_timeout(void * context)
|
||||
{
|
||||
if(NULL!=context)
|
||||
{
|
||||
free(context);
|
||||
}
|
||||
}
|
||||
|
||||
void free_query_detail(query_detail_t* query_detail)
|
||||
{
|
||||
if(NULL!=query_detail)
|
||||
{
|
||||
switch(query_detail->addrtype)
|
||||
{
|
||||
case ADDR_TYPE_IPV4:
|
||||
if(NULL!=query_detail->tuple4_v4)
|
||||
{
|
||||
free(query_detail->tuple4_v4);
|
||||
}
|
||||
break;
|
||||
case ADDR_TYPE_IPV6:
|
||||
if(NULL!=query_detail->tuple4_v6)
|
||||
{
|
||||
free(query_detail->tuple4_v6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(NULL!=query_detail->url)
|
||||
{
|
||||
free((void*)query_detail->url);
|
||||
}
|
||||
free(query_detail);
|
||||
}
|
||||
}
|
||||
|
||||
void proc_media_multisrc(media_t* mdi, int timeout)
|
||||
{
|
||||
query_detail_t* query_detail = NULL;
|
||||
struct stream_tuple4_v4 tuple4_v4 ;
|
||||
struct stream_tuple4_v6 tuple4_v6 ;
|
||||
|
||||
/*<2A>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ*/
|
||||
/*<2A><><EFBFBD><D7BC>ʱ֮<CAB1><D6AE>һ<EFBFBD><D2BB><EFBFBD>ᷢ<EFBFBD><E1B7A2><EFBFBD><EFBFBD>ѯ*/
|
||||
if(!FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_YES)&&
|
||||
(((FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_DEDUP)||mdi->byte_proc>g_frag_cfg.td_data_maxsize)
|
||||
&& FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_MULTISRC))||timeout))
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>td_meta,<2C>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD>td*/
|
||||
if((g_frag_cfg.av_dedup_switch) && (mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index] == NULL))
|
||||
{
|
||||
generate_td_meta(mdi);
|
||||
if(mdi->td_complete != 1 && mdi->td_datalen==g_frag_cfg.td_data_maxsize)
|
||||
{
|
||||
caculate_md5(mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len, mdi->td_data, mdi->td_datalen, mdi->td, TD_LEN);
|
||||
mdi->td_complete = 1;
|
||||
}
|
||||
}
|
||||
|
||||
FLAG_SET(mdi->td_query, TD_QUERY_TYPE_YES);
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ж<EFBFBD>Դ<EFBFBD><D4B4><EFBFBD>߽<EFBFBD><DFBD>ز<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>query_detail*/
|
||||
query_detail = (query_detail_t*)calloc(1, sizeof(query_detail_t));
|
||||
query_detail->total_len = mdi->media_len;
|
||||
query_detail->mid = mdi->mid;
|
||||
|
||||
/*addr*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index])
|
||||
{
|
||||
query_detail->addrtype = addrlist_to_streamtuple4(mdi->opt[MEDIA_OPT_ADDR][mdi->url_opt_index]->opt_value, &tuple4_v4, &tuple4_v6);
|
||||
switch(query_detail->addrtype)
|
||||
{
|
||||
case ADDR_TYPE_IPV4:
|
||||
query_detail->tuple4_v4 = (struct stream_tuple4_v4*)malloc(sizeof(struct stream_tuple4_v4));;
|
||||
memcpy(query_detail->tuple4_v4, &tuple4_v4, sizeof(tuple4_v4));
|
||||
break;
|
||||
case ADDR_TYPE_IPV6:
|
||||
query_detail->tuple4_v6 = (struct stream_tuple4_v6*)malloc(sizeof(struct stream_tuple4_v6));;
|
||||
memcpy(query_detail->tuple4_v6, &tuple4_v6, sizeof(tuple4_v6));
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*<2A><>Դ<EFBFBD><D4B4>ѯ*/
|
||||
if(FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_MULTISRC))
|
||||
{
|
||||
/*<2A><><EFBFBD>ö<EFBFBD>ʱ<EFBFBD><CAB1>*/
|
||||
struct timer_context_t *context = (struct timer_context_t *)calloc(1, sizeof(struct timer_context_t));
|
||||
context->mid = mdi->mid;
|
||||
MESA_timer_add(g_frag_run.multisrc_timer[mdi->thread_seq],
|
||||
time(NULL),
|
||||
g_frag_cfg.multisrc_wait_timeout,
|
||||
soqav_query_timeout,
|
||||
context,
|
||||
soqav_query_free_timeout,
|
||||
&mdi->timer_idx);
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index])
|
||||
{
|
||||
query_detail->url = (char*)malloc(mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
query_detail->urllen = mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len;
|
||||
memcpy((void*)query_detail->url, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_URL][mdi->url_opt_index]->opt_len);
|
||||
}
|
||||
}
|
||||
if(FLAG_TEST(mdi->td_query, TD_QUERY_TYPE_DEDUP))
|
||||
{
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_TD_QUERY]);
|
||||
soqav_dedup_query(g_frag_run.dedup_hd, mdi->td, query_detail, soqav_query_callback, (void*)mdi->mid);
|
||||
}
|
||||
else
|
||||
{
|
||||
soqav_dedup_query(g_frag_run.dedup_hd, NULL, query_detail, soqav_query_callback, (void*)mdi->mid);
|
||||
}
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_DEDUP_QUERY]);
|
||||
frag_write_to_log(SEND_AV_DEDUP_QUERY, mdi->mid, mdi, NULL, 0);
|
||||
if(NULL!=query_detail)
|
||||
{
|
||||
free_query_detail(query_detail);
|
||||
query_detail =NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
src/frag_dedup.h
Normal file
34
src/frag_dedup.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef _FRAG_DEDUP_H
|
||||
#define _FRAG_DEDUP_H
|
||||
|
||||
#define TD_QUERY_TYPE_DEDUP 0x01 //<2F><><EFBFBD>ز<EFBFBD>ѯ<EFBFBD><D1AF>־λ
|
||||
#define TD_QUERY_TYPE_MULTISRC 0x02 //<2F><>Դ<EFBFBD><D4B4>ѯ<EFBFBD><D1AF>־λ
|
||||
#define TD_QUERY_TYPE_YES 0x04 //<2F><>ѯ<EFBFBD>ı<EFBFBD>־λ
|
||||
#define TD_QUERY_ACK_DEDUP 0x10 //<2F><><EFBFBD>ز<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD><EFBFBD><EFBFBD>־λ
|
||||
#define TD_QUERY_ACK_MULTISRC 0x20 //<2F><>Դ<EFBFBD><D4B4>ѯ<EFBFBD><D1AF><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD><EFBFBD><EFBFBD>־λ
|
||||
#define TD_QUERY_RES_DEDUP 0x40 //<2F><><EFBFBD>ر<EFBFBD>ʶ
|
||||
#define TD_QUERY_RES_MULTISRC 0x80 //<2F><>Դ<EFBFBD><D4B4>ʶ
|
||||
#define TD_QUERY_RES_NOREPORT 0x08 //<2F>ϱ<EFBFBD><CFB1><EFBFBD>ʶ
|
||||
|
||||
struct timer_context_t
|
||||
{
|
||||
uint64_t mid;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void generate_td_meta(media_t* mdi);
|
||||
long set_td_data(media_t* mdi, frag_in_t* frg);
|
||||
void media_dedup_report(media_t* mdi);
|
||||
void free_query_detail(query_detail_t* query_detail);
|
||||
void proc_media_multisrc(media_t* mdi, int timeout);
|
||||
long soqav_query_callback(const char *td, const query_result_t* result, void *user_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
354
src/frag_json.c
Normal file
354
src/frag_json.c
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* <20><>ý<EFBFBD><C3BD>:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "stream_fuzzy_hash.h"
|
||||
#include "AV_sendback_in.h"
|
||||
#include "frag_json.h"
|
||||
#include "frag_proc.h"
|
||||
#include "log.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
|
||||
extern sip_opt_t g_sip_opt_type[SIP_OPT_NUM];
|
||||
|
||||
const char* g_td_des_json[] =
|
||||
{
|
||||
"data_md5_1k",
|
||||
"td_1k",
|
||||
"data_md5_2k",
|
||||
"td_2k",
|
||||
"data_md5_4k",
|
||||
"td_4k" ,
|
||||
"data_md5_8k",
|
||||
"td_8k" ,
|
||||
"data_md5_16k",
|
||||
"td_16k",
|
||||
"data_md5_32k",
|
||||
"td_32k",
|
||||
"data_md5_64k",
|
||||
"td_64k",
|
||||
};
|
||||
|
||||
/*<2A><>kafka<6B><61>ѡ<EFBFBD><D1A1>*/
|
||||
#define JSON_MAXOPT 8
|
||||
int json_opt[JSON_MAXOPT] = {MEDIA_OPT_CAP_IP,MEDIA_OPT_URL, MEDIA_OPT_REFERER, MEDIA_OPT_UA, MEDIA_OPT_SINGLE_KEY, MEDIA_OPT_ETAG, MEDIA_OPT_LAST_MODIFY, MEDIA_OPT_SERVER};
|
||||
const char* json_optname[JSON_MAXOPT] = {"cap_ip", "url", "referer", "ua", "single_key", "etag", "last_modify", "server"};
|
||||
void media_json_report(media_t* mdi, int topic_event)
|
||||
{
|
||||
cJSON* root;
|
||||
char* digest_buff = NULL;
|
||||
unsigned long long digest_len = 0;
|
||||
uint64_t pid = 0;
|
||||
cJSON* ip_array = NULL;
|
||||
cJSON* pid_array = NULL;
|
||||
cJSON* muti_url_array = NULL;
|
||||
uint32_t ip = 0;
|
||||
char* out = NULL;
|
||||
uint32_t out_len = 0;
|
||||
char pbuf[32] = {0};
|
||||
int buf_len = 32;
|
||||
char filename[64] = {0};
|
||||
FILE* fp = NULL;
|
||||
string topic_name;
|
||||
const char* topic = NULL;
|
||||
char pid_buf[32] = {0};
|
||||
char td[TD_LEN] = {0};
|
||||
int cb_ret = 0;
|
||||
touple4_type_t touple4;
|
||||
|
||||
if(topic_event==TOPIC_EVENT_CREATE)
|
||||
{
|
||||
if(mdi->proto==AV_PROTOCOL_SIP)
|
||||
{
|
||||
topic = TOPIC_VOIP_CREATE_JSON;
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = TOPIC_MEDIA_CREATE_JSON;
|
||||
}
|
||||
}
|
||||
else if(topic_event==TOPIC_EVENT_EXPIRE)
|
||||
{
|
||||
if(mdi->proto==AV_PROTOCOL_SIP)
|
||||
{
|
||||
topic = TOPIC_VOIP_EXPIRE_JSON;
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = TOPIC_MEDIA_EXPIRE_JSON;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
topic_name = topic;
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
/*mid*/
|
||||
snprintf(pid_buf, sizeof(pid_buf), "%lu", mdi->mid);
|
||||
cJSON_AddStringToObject(root, "mid", pid_buf);
|
||||
|
||||
/*trans_len*/
|
||||
cJSON_AddNumberToObject(root, "trans_len", mdi->byte_proc);
|
||||
|
||||
/*media_len*/
|
||||
cJSON_AddNumberToObject(root, "media_len", mdi->media_len);
|
||||
|
||||
/*media_type*/
|
||||
cJSON_AddNumberToObject(root, "media_type", mdi->media_type);
|
||||
|
||||
/*create_time*/
|
||||
cJSON_AddNumberToObject(root, "create_time", mdi->create_time);
|
||||
|
||||
/*expire_time*/
|
||||
cJSON_AddNumberToObject(root, "expire_time", time(NULL));
|
||||
|
||||
/*cpz_ip*/
|
||||
memset(pbuf, 0, sizeof(pbuf));
|
||||
inet_ntop(AF_INET, &g_frag_cfg.local_ip_nr, pbuf, buf_len);
|
||||
cJSON_AddStringToObject(root, "cpz_ip", pbuf);
|
||||
|
||||
/*pid*/
|
||||
if(NULL!=mdi->pid)
|
||||
{
|
||||
pid_array = cJSON_CreateArray();
|
||||
for(int i=0;i<PID_MAXNUM;i++)
|
||||
{
|
||||
pid = mdi->pid[i];
|
||||
if(!pid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
memset(pid_buf, 0, sizeof(pid_buf));
|
||||
snprintf(pid_buf, sizeof(pid_buf), "%lu", pid);
|
||||
cJSON_AddStringToObject(pid_array, "pid", pid_buf);
|
||||
}
|
||||
cJSON_AddItemToObject(root, "pid", pid_array);
|
||||
}
|
||||
|
||||
/*cap_ip*/
|
||||
ip_array = cJSON_CreateArray();
|
||||
for(int i=0;i<QD_MAXNUM;i++)
|
||||
{
|
||||
ip = mdi->qd_info[i].cap_ip;
|
||||
if(!ip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
memset(pbuf, 0, sizeof(pbuf));
|
||||
inet_ntop(AF_INET, &ip, pbuf, buf_len);
|
||||
cJSON_AddStringToObject(ip_array, "cap_ip", pbuf);
|
||||
}
|
||||
cJSON_AddItemToObject(root, "cap_ip", ip_array);
|
||||
|
||||
/*SIP<49><50>¼<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>*/
|
||||
if(mdi->media_service_type==MEDIA_SERVICE_TYPE_SIP)
|
||||
{
|
||||
cJSON_AddNumberToObject(root, "pkt_in", mdi->pkt_in);
|
||||
cJSON_AddNumberToObject(root, "pkt_out", mdi->pkt_proc);
|
||||
cJSON_AddNumberToObject(root, "byte_in", mdi->byte_in);
|
||||
cJSON_AddNumberToObject(root, "byte_out", mdi->byte_proc);
|
||||
cJSON_AddNumberToObject(root, "reoffset", mdi->re_offset);
|
||||
char buf[128] = {0};
|
||||
for(int i=0;i<SIP_OPT_NUM;i++)
|
||||
{
|
||||
if(NULL!=mdi->sip_opt[i])
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, mdi->sip_opt[i]->opt_value, MIN(mdi->sip_opt[i]->opt_len, 127));
|
||||
cJSON_AddStringToObject(root, g_sip_opt_type[i].opt_name, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*digest*/
|
||||
if(NULL!=mdi->fuzzy)
|
||||
{
|
||||
digest_len = SFH_status(mdi->fuzzy, HASH_LENGTH);
|
||||
digest_buff = (char*)calloc(1, sizeof(char)*digest_len+1);
|
||||
SFH_digest(mdi->fuzzy, digest_buff, digest_len);
|
||||
cJSON_AddStringToObject(root, "digest", digest_buff);
|
||||
}
|
||||
/*digest_len*/
|
||||
cJSON_AddNumberToObject(root, "digest_len", digest_len);
|
||||
|
||||
/*multi_url*/
|
||||
char opt_temp[JSON_MAXOPT][4096] = {{0}};
|
||||
cJSON* url_obj[OPT_MAXNUN] = {NULL};
|
||||
muti_url_array = cJSON_CreateArray();
|
||||
for(int i=0;i<mdi->opt_index;i++)
|
||||
{
|
||||
url_obj[i] = cJSON_CreateObject();
|
||||
|
||||
//pid
|
||||
memset(pid_buf, 0, sizeof(pid_buf));
|
||||
snprintf(pid_buf, sizeof(pid_buf), "%lu", *(uint64_t*)mdi->opt[MEDIA_OPT_PID][i]->opt_value);
|
||||
cJSON_AddStringToObject(url_obj[i], "pid", pid_buf);
|
||||
|
||||
//addr
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_ADDR][i])
|
||||
{
|
||||
if(sscanf(mdi->opt[MEDIA_OPT_ADDR][i]->opt_value, "%[0-9.],%hu>%[0-9.],%hu", touple4.sip, &touple4.sport, touple4.dip, &touple4.dport) == 4)
|
||||
{
|
||||
touple4.addr_type = 4;
|
||||
}
|
||||
else if(sscanf(mdi->opt[MEDIA_OPT_ADDR][i]->opt_value, "%[0-9A-Fa-f:.],%hu>%[0-9A-Fa-f:.],%hu", touple4.sip, &touple4.sport, touple4.dip, &touple4.dport) == 4)
|
||||
{
|
||||
touple4.addr_type = 6;
|
||||
}
|
||||
cJSON_AddStringToObject(url_obj[i], "s_ip", touple4.sip);
|
||||
cJSON_AddNumberToObject(url_obj[i], "s_port", touple4.sport);
|
||||
cJSON_AddStringToObject(url_obj[i], "d_ip", touple4.dip);
|
||||
cJSON_AddNumberToObject(url_obj[i], "d_port", touple4.dport);
|
||||
}
|
||||
|
||||
//protocol
|
||||
cJSON_AddNumberToObject(url_obj[i], "protocol", *(uint8_t*)mdi->opt[MEDIA_OPT_PROTOCOL][i]->opt_value);
|
||||
|
||||
//others
|
||||
for(int j=0;j<JSON_MAXOPT;j++)
|
||||
{
|
||||
if(NULL!=mdi->opt[json_opt[j]][i])
|
||||
{
|
||||
memcpy(opt_temp[j], mdi->opt[json_opt[j]][i]->opt_value, MIN(sizeof(opt_temp[j])-1, mdi->opt[json_opt[j]][i]->opt_len));
|
||||
cJSON_AddStringToObject(url_obj[i], json_optname[j], opt_temp[j]);
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToObject(muti_url_array, "multi_session", url_obj[i]);
|
||||
}
|
||||
cJSON_AddItemToObject(root, "multi_session", muti_url_array);
|
||||
|
||||
/*index_url*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_INDEX_URL][mdi->url_opt_index])
|
||||
{
|
||||
cJSON_AddStringToObject(root, "index_url", mdi->opt[MEDIA_OPT_INDEX_URL][mdi->url_opt_index]->opt_value);
|
||||
}
|
||||
/*index_referer*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_INDEX_REFERER][mdi->url_opt_index])
|
||||
{
|
||||
cJSON_AddStringToObject(root, "index_referer", mdi->opt[MEDIA_OPT_INDEX_REFERER][mdi->url_opt_index]->opt_value);
|
||||
}
|
||||
/*index_ua*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_INDEX_UA][mdi->url_opt_index])
|
||||
{
|
||||
cJSON_AddStringToObject(root, "index_ua", mdi->opt[MEDIA_OPT_INDEX_UA][mdi->url_opt_index]->opt_value);
|
||||
}
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
if(NULL!=mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index])
|
||||
{
|
||||
/*td_meta*/
|
||||
cJSON_AddStringToObject(root, "td_meta", mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value);
|
||||
|
||||
/*td_0k*/
|
||||
caculate_md5(mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len, NULL, 0, td, TD_LEN);
|
||||
cJSON_AddStringToObject(root, "td_0k", td);
|
||||
|
||||
/*data_md5_1k*/ /*td_1k*/
|
||||
/*data_md5_2k*/ /*td_2k*/
|
||||
/*data_md5_4k*/ /*td_4k*/
|
||||
/*data_md5_8k*/ /*td_8k*/
|
||||
/*data_md5_16k*/ /*td_16k*/
|
||||
/*data_md5_32k*/ /*td_32k*/
|
||||
/*data_md5_64k*/ /*td_64k*/
|
||||
uint32 i=0;
|
||||
for(int j=0;j<=6;j++)
|
||||
{
|
||||
i=1<<j;
|
||||
if(mdi->td_datalen>=i*1024)
|
||||
{
|
||||
caculate_md5(NULL, 0, mdi->td_data, i*1024, td, TD_LEN);
|
||||
cJSON_AddStringToObject(root, g_td_des_json[2*j], td);
|
||||
|
||||
caculate_md5(mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_value, mdi->opt[MEDIA_OPT_TD_META][mdi->url_opt_index]->opt_len, mdi->td_data, i*1024, td, TD_LEN);
|
||||
cJSON_AddStringToObject(root, g_td_des_json[2*j+1], td);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*<2A><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>*/
|
||||
/*cfg_id*/
|
||||
cJSON_AddNumberToObject(root, "cfg_id", mdi->cfg_id);
|
||||
|
||||
/*service*/
|
||||
cJSON_AddNumberToObject(root, "service", mdi->service);
|
||||
|
||||
/*level*/
|
||||
cJSON_AddNumberToObject(root, "level", mdi->level);
|
||||
|
||||
/*survey time*/
|
||||
cJSON_AddNumberToObject(root, "survey_time", mdi->survey_time);
|
||||
|
||||
/*log_url*/
|
||||
cJSON_AddStringToObject(root, "log_url", mdi->log_url);
|
||||
|
||||
//out = cJSON_PrintUnformatted(root);
|
||||
out = cJSON_Print(root);
|
||||
out_len = strlen(out);
|
||||
|
||||
cb_ret = g_frag_run.kafka_producer->SendData(topic_name, (void *)out, (size_t)out_len);
|
||||
if(0!=cb_ret)
|
||||
{
|
||||
/*fail output*/
|
||||
atomic_inc(&g_frag_stat.stat_info[MEDIA_JSON][FAIL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[MEDIA_JSON][FAIL_BYTES], out_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*succ output*/
|
||||
atomic_inc(&g_frag_stat.stat_info[MEDIA_JSON][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[MEDIA_JSON][TOTAL_BYTES], out_len);
|
||||
}
|
||||
|
||||
/*for debug*/
|
||||
if(g_frag_cfg.json_local_switch)
|
||||
{
|
||||
struct tm now;
|
||||
char day_time[32] = {0};
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv, &tz);
|
||||
localtime_r(&tv.tv_sec, &now);
|
||||
strftime(day_time, sizeof(day_time), "%Y-%m-%d", &now);
|
||||
snprintf(filename, sizeof(filename), "%s%s%s_%s", "./log/", topic, ".json", day_time);
|
||||
if(NULL!=(fp=fopen(filename,"a+")))
|
||||
{
|
||||
fwrite(out, strlen(out), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
|
||||
if(NULL!=out)
|
||||
{
|
||||
free(out);
|
||||
}
|
||||
if(NULL!=digest_buff)
|
||||
{
|
||||
free(digest_buff);
|
||||
}
|
||||
}
|
||||
|
||||
28
src/frag_json.h
Normal file
28
src/frag_json.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _FRAG_JSON_H
|
||||
#define _FRAG_JSON_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
#define TOPIC_EVENT_CREATE 0
|
||||
#define TOPIC_EVENT_EXPIRE 1
|
||||
|
||||
/*¿çýÌ廨´«JSONÐÅÏ¢µÄtopic_name*/
|
||||
#define TOPIC_MEDIA_CREATE_JSON "MEDIA_CREATE_INFO"
|
||||
#define TOPIC_MEDIA_EXPIRE_JSON "MEDIA_EXPIRE_INFO"
|
||||
#define TOPIC_SURVEY_JSON "SURVEY_INFO"
|
||||
|
||||
#define TOPIC_VOIP_CREATE_JSON "VOIP_CREATE_INFO"
|
||||
#define TOPIC_VOIP_EXPIRE_JSON "VOIP_EXPIRE_INFO"
|
||||
#define TOPIC_VOIP_SURVEY_JSON "VOIP_SURVEY_INFO"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void media_json_report(media_t* mdi, int topic_event);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
1721
src/frag_proc.c
Normal file
1721
src/frag_proc.c
Normal file
File diff suppressed because it is too large
Load Diff
42
src/frag_proc.h
Normal file
42
src/frag_proc.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef _FRAG_PROC_H
|
||||
#define _FRAG_PROC_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
#define PID_TYPE_DEF 0
|
||||
#define PID_TYPE_URL 1
|
||||
#define PID_TYPE_IPLEN 2
|
||||
#define PID_TYPE_CON 3
|
||||
#define PID_TYPE_ADDR 4
|
||||
#define PID_TYPE_COUNT 5
|
||||
#define PID_TYPE_RESORT 6
|
||||
#define PID_TYPE_IMAGE 7
|
||||
|
||||
#define FLAG_SET(x, flag) ((x) |= (flag))
|
||||
#define FLAG_CLEAR(x, flag) ((x) &= ~(flag))
|
||||
#define FLAG_TEST(x, flag) (0 != ((x) & (flag)))
|
||||
|
||||
#define SET_BIT(x, n) ( (x) |= (1<<n) )
|
||||
#define GET_BIT(x, n) ( ((x)>>(n)) & 1 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void create_media_write_to_log(media_t* mdi, int type, void* param);
|
||||
void expire_media_write_to_log(media_t* mdi, int type, void* param);
|
||||
void send_ack_to_qd(frag_in_t* frg, uint32_t src_ip, int thread_seq);
|
||||
int get_serverIP(const char *addr, uint32_t addr_len, char* d_ip);
|
||||
int save_qd_info(qd_info_t qd_info[], uint32_t qd_info_maxnum, uint8_t* qd_info_idx_last, uint32_t capip, uint64_t mid);
|
||||
void frag_write_to_log(int type, uint64_t mid, void* param1, void* param2, uint32_t param3);
|
||||
int caculate_md5(const char *meta, unsigned long meta_len, const char *data, unsigned long len, char *result, unsigned int result_len);
|
||||
int frag_unit_removal(media_t* mdi, uint64_t reoffset);
|
||||
int frag_removal_and_merge(IVI_t* ivi, frag_ivi_info_t* frag_ivi_info);
|
||||
char* merge_addr(char* addr_buf, uint32_t* addr_buflen, char* opt_addr, uint32_t opt_addrlen, int thread_seq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
1639
src/frag_reassembly.c
Normal file
1639
src/frag_reassembly.c
Normal file
File diff suppressed because it is too large
Load Diff
70
src/frag_reassembly.h
Normal file
70
src/frag_reassembly.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef _FRAG_REASSEMBLY_H
|
||||
#define _FRAG_REASSEMBLY_H
|
||||
|
||||
|
||||
#define RETURN_FRAG 0x01
|
||||
#define RETURN_MEDIA 0x02
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_INFO_NAME=0,
|
||||
MEDIA_INFO_MAXNUM,
|
||||
}MEDIA_INFO_TYPE;
|
||||
|
||||
/*more opt_unit than msg_metainfo_t*/
|
||||
typedef struct media_info_s
|
||||
{
|
||||
uint64_t mid;
|
||||
char flag;
|
||||
#if K_PROJECT
|
||||
int hitservice;
|
||||
uint8_t pad[5];
|
||||
#else
|
||||
uint8_t hitservice;
|
||||
#endif
|
||||
uint64_t prog_len:48;
|
||||
uint32_t cap_IP;
|
||||
uint8_t protocol;
|
||||
uint8_t media_type;
|
||||
uint8_t data_flag;
|
||||
uint8_t opt_num;
|
||||
struct opt_unit_t* opt_unit;
|
||||
uint32_t multisrc_bizmanip;
|
||||
int8_t mdi_flag; //same with media_t
|
||||
int8_t td_query;
|
||||
}media_info_t;
|
||||
|
||||
/*same with AV_type.h*/
|
||||
struct opt_unit_t
|
||||
{
|
||||
uint32_t opt_len; //include this variable
|
||||
uint8_t opt_type;
|
||||
char* opt_value;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
1. frag_rssb_cfg_dir: path of config file; frag_rssb_log_dir: path of log file
|
||||
2. return value: (0:succ -1:error)
|
||||
*/
|
||||
int frag_reassembly_init(const char* frag_rssb_cfg_dir, const char* frag_rssb_log_dir, int thread_num);
|
||||
void frag_reassembly_release();
|
||||
|
||||
/*
|
||||
1. return value: ( 0: succ -1:error )
|
||||
2.data will be copied.
|
||||
*/
|
||||
int add_media_info(msg_metainfo_t* minfo, char* opt, uint32_t src_ip, int thread_seq);
|
||||
//int add_media_info(uint64_t pid, uint16_t media_type, uint64_t media_len, uint8_t protocol, uint8_t hitservice, uint8_t data_flag, uint32_t cap_IP, char* opt, int opt_num, int thread_seq);
|
||||
int add_frag(uint64_t pid, uint64_t offset, char* data, uint32_t datalen, uint8_t protocol, uint32_t src_ip, int thread_seq);
|
||||
long get_media(void *data, const uint8_t *key, uint size, void *user_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
454
src/frag_reassembly_in.h
Normal file
454
src/frag_reassembly_in.h
Normal file
@@ -0,0 +1,454 @@
|
||||
#ifndef _FRAG_REASSEMBLY_IN_H
|
||||
#define _FRAG_REASSEMBLY_IN_H
|
||||
|
||||
#include </usr/include/stdint.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include "stream_fuzzy_hash.h"
|
||||
#include "MESA_list_queue.h"
|
||||
#include "MESA_timer.h"
|
||||
|
||||
#include "interval_index.h"
|
||||
#include "hiredis.h"
|
||||
#include "hircluster.h"
|
||||
#include "soqav_dedup.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "sifter.h"
|
||||
#include "frag_reassembly.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
#define LAY_ADDR_CNT 8
|
||||
#define PID_MAX_LEN 64
|
||||
#define SIFTER_MAX_NUM 8 //for sifter
|
||||
|
||||
#define TD_LEN 64
|
||||
#define REDIS_CMMD_MAXLEN 2048 /*redis<69><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
|
||||
/*<2A><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>ǰ<EFBFBD>˻<EFBFBD><CBBB><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define QD_MAXNUM 8
|
||||
|
||||
/*log type*/
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_NEW=0,
|
||||
MEDIA_RENEW,
|
||||
MEDIA_RENEW_EXPIRE,
|
||||
MEDIA_EXPIRE,
|
||||
MEDIA_MID_CHANGE,
|
||||
MEDIA_OFFSET_ZERO,
|
||||
MEDIA_FROM_CAPIP,
|
||||
MEDIA_FROM_CPZIP,
|
||||
MEDIA_FROM_QDIP,
|
||||
}MEDIA_LOG_TYPE;
|
||||
|
||||
/*response from frag_index*/
|
||||
#define CONVG_MAXNUM 16
|
||||
typedef struct frag_cnvg_s
|
||||
{
|
||||
text_t* opt[CONVG_MAXNUM];
|
||||
int opt_num;
|
||||
}frag_cnvg_t;
|
||||
|
||||
/*opt_unit_t is for trans*/
|
||||
typedef struct opt_in_s
|
||||
{
|
||||
uint32_t opt_len; //the len of opt_value in CPZ
|
||||
uint8_t opt_type;
|
||||
char* opt_value;
|
||||
}opt_in_t;
|
||||
|
||||
#define FRAG_FLAG_SEND_META 0x01 //<2F><>Ŀ<EFBFBD>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>Ϣ
|
||||
#define FRAG_FLAG_MULTISRC 0x02 //<2F><>Դ<EFBFBD><D4B4>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿװ
|
||||
#define FRAG_FLAG_WINS 0x04 //<2F><>ϵͳ<CFB5><CDB3>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>wins
|
||||
typedef struct frag_in_s
|
||||
{
|
||||
uint64_t mid;
|
||||
uint64_t new_mid; //<2F>Ƕ<EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:mid=new_mid; <20><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:new_midΪ<64><CEAA>Դ<EFBFBD><D4B4><EFBFBD>۵<EFBFBD>ID
|
||||
uint64_t pid;
|
||||
uint64_t offset_in;
|
||||
uint16_t seq;
|
||||
uint64_t offset:48;
|
||||
char* data; //not copy
|
||||
uint32_t datalen;
|
||||
uint32_t multisrc_bizmanip; //<2F><>Դ<EFBFBD>ۺϵ<DBBA>IP
|
||||
// int64_t create_time;
|
||||
uint32_t src_ip;
|
||||
int thread_seq; //record thread_seq when converge is not complete
|
||||
int frag_flag; //<2F><><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ı<EFBFBD>־
|
||||
// uint8_t media_type;
|
||||
// uint8_t proto;
|
||||
}frag_in_t;
|
||||
|
||||
/*netdisk and other frag*/
|
||||
#define FRAG_UNIT_INFO_NUM 6
|
||||
typedef enum
|
||||
{
|
||||
FRAG_UNIT_ID=0, //from frag_sifter
|
||||
FRAG_UNIT_ABOFFSET=1, //maybe from index info or frag_sifter
|
||||
FRAG_UNIT_REOFFSET=2, //maybe from index info or frag_sifter
|
||||
MEDIA_ID=3, //maybe from index info or frag_sifter
|
||||
MEDIA_SIZE=4, //maybe from index info or frag_sifter
|
||||
MEDIA_NAME=5, //maybe from index info or frag_sifter
|
||||
}FRAG_UNIT_INFO;
|
||||
|
||||
/*frag_stat <20><><EFBFBD>ε<EFBFBD>״̬*/
|
||||
#define STAT_INIT 0x00
|
||||
#define STAT_CNVG_QUERY 0x01 //query but not result
|
||||
#define STAT_CNVG_OK 0x02
|
||||
#define STAT_INDEX_QUERY 0x03
|
||||
#define STAT_OK 0x04
|
||||
|
||||
/* frag_unit_t flag*/
|
||||
#define FRAG_UNIT_ADDMEDIA 0x01
|
||||
#define FRAG_UNIT_MONITOR 0x02
|
||||
#define FRAG_UNIT_OFFSET 0x04
|
||||
#define FRAG_UNIT_RECORD 0x08
|
||||
#define FRAG_UNIT_MULTI 0x10
|
||||
|
||||
#define WEBMAIL_CONT_INFO_NUM 10
|
||||
|
||||
/*SIPѡ<50><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define SIP_OPT_NUM 32
|
||||
/*SIP<49><50>ѯredis<69><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define SIP_REDIS_CMMD_NUM 34
|
||||
/*SIP<49><50>ѡ<EFBFBD><D1A1>*/
|
||||
typedef struct sip_opt_s
|
||||
{
|
||||
char opt_name[32];
|
||||
int opt_type; /*<2A><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>JC<4A><43>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
}sip_opt_t;
|
||||
|
||||
typedef struct qd_info_s
|
||||
{
|
||||
uint64_t mid;
|
||||
uint32_t cap_ip;
|
||||
}qd_info_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_OPT_URL=0,
|
||||
MEDIA_OPT_PID,
|
||||
MEDIA_OPT_ADDR,
|
||||
MEDIA_OPT_SINGLE_KEY,
|
||||
MEDIA_OPT_UA,
|
||||
MEDIA_OPT_REFERER,
|
||||
MEDIA_OPT_ETAG,
|
||||
MEDIA_OPT_LAST_MODIFY,
|
||||
MEDIA_OPT_SERVER,
|
||||
MEDIA_OPT_TD_META,
|
||||
MEDIA_OPT_OFFSET,
|
||||
MEDIA_OPT_C2S_CONT_TYPE,
|
||||
MEDIA_OPT_S2C_CONT_TYPE,
|
||||
MEDIA_OPT_CAP_IP,
|
||||
MEDIA_OPT_PROTOCOL,
|
||||
|
||||
MEDIA_OPT_INDEX_URL,
|
||||
MEDIA_OPT_INDEX_REFERER,
|
||||
MEDIA_OPT_INDEX_UA,
|
||||
MEDIA_OPT_FD_SUBSTR,
|
||||
|
||||
MEDIA_OPT_S_IP,
|
||||
MEDIA_OPT_S_PORT,
|
||||
MEDIA_OPT_C_IP,
|
||||
MEDIA_OPT_C_PORT,
|
||||
|
||||
MEDIA_OPT_MAXNUN,
|
||||
}MEDIA_OPT;
|
||||
|
||||
typedef struct frag_unit_s
|
||||
{
|
||||
MESA_lqueue_head frg_cnvg_lq;
|
||||
MESA_lqueue_head frg_index_lq;
|
||||
text_t** frg_info; //useful info after sifter
|
||||
|
||||
text_t* text; //from media_info opt to sifter
|
||||
int text_num;
|
||||
int thread_seq;
|
||||
|
||||
uint64_t pid; //from media_info
|
||||
uint64_t media_len; //from media_info
|
||||
|
||||
uint32_t capIP; //<2F><>ƿװ<C6BF><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ǰ<EFBFBD>˻<EFBFBD><CBBB><EFBFBD>IP
|
||||
uint32_t src_ip;
|
||||
|
||||
#if K_PROJECT
|
||||
int hitservice; //from media_info
|
||||
#else
|
||||
uint8_t hitservice; //from media_info
|
||||
uint8_t pad[3];
|
||||
#endif
|
||||
uint8_t data_flag; //from media_info
|
||||
int8_t flag; //from media_info
|
||||
uint8_t media_type; //from media_info
|
||||
uint8_t proto; //from data
|
||||
|
||||
qd_info_t qd_info_from_cpz[QD_MAXNUM]; //ǰ<>˻<EFBFBD><CBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
opt_in_t* opt[MEDIA_OPT_MAXNUN];
|
||||
uint64_t content_length; //from media_info opt
|
||||
|
||||
uint64_t mid;
|
||||
uint64_t re_offset;
|
||||
uint64_t ab_offset;
|
||||
uint64_t ab_offset_for_in;
|
||||
uint64_t ab_offset_for_mime; //mime extract data, update offset
|
||||
|
||||
int service_id;
|
||||
uint32_t mediainfo_cnt;
|
||||
|
||||
uint8_t repeat_not_proc; //such hls, osmf , same reoffset
|
||||
uint8_t frag_state;
|
||||
uint8_t multi_flag;
|
||||
uint8_t qd_info_from_cpz_idx_last;
|
||||
|
||||
opt_in_t* sip_diadata_ID; //<2F>洢META_OPT_SIP_DIADATA_ID
|
||||
opt_in_t* sip_data_dir; //<2F>洢META_OPT_SIP_DATA_DIR
|
||||
opt_in_t* sip_rate_info; //<2F>洢META_OPT_SIP_DATA_DIR
|
||||
opt_in_t* sip_opt[SIP_OPT_NUM];
|
||||
}frag_unit_t;
|
||||
|
||||
#define INFO_MEDIA_NUM 1
|
||||
#define PID_MAXNUM 256
|
||||
#define KEEP_REOFFSET_MAXNUM 2048
|
||||
|
||||
/*<2A><>Դ<EFBFBD><D4B4>ѯ<EFBFBD><D1AF><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>ǰ<EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
struct queue_item
|
||||
{
|
||||
void* node;
|
||||
int thread_seq;
|
||||
TAILQ_ENTRY(queue_item) entries;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(qw_queue, queue_item);
|
||||
|
||||
#define AUDIO_WINS_DISABLE 0x01
|
||||
#define VEDIO_WINS_DISABLE 0x02
|
||||
|
||||
#define SIP_SURVEY_TYPE_FD 0x01
|
||||
#define SIP_SURVEY_TYPE_JC 0x02
|
||||
#define SIP_SURVEY_TYPE_FD_JC 0x03
|
||||
|
||||
#define MEDIA_SERVICE_TYPE_AV 0x00
|
||||
#define MEDIA_SERVICE_TYPE_FRAG 0x01
|
||||
#define MEDIA_SERVICE_TYPE_SIP 0x02
|
||||
#define MEDIA_SERVICE_TYPE_APP 0x03
|
||||
#define MEDIA_SERVICE_TYPE_PIC 0x04
|
||||
|
||||
/*ÿ<><C3BF><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
|
||||
#define OPT_MAXNUN 256
|
||||
typedef struct media_s
|
||||
{
|
||||
IVI_t* ivi; //complete frag removal
|
||||
IVI_t* save_ivi;
|
||||
sfh_instance_t* fuzzy;
|
||||
uint64_t fuzzy_acc_len; //SFH_feed acc len
|
||||
|
||||
MESA_lqueue_head app_frg_lq; //app<70><70><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
||||
|
||||
text_t* media_info[INFO_MEDIA_NUM]; //MEDIA_INFO_TYPE
|
||||
|
||||
uint64_t mid_after_multisrc; //<2F><>Դ֮<D4B4><D6AE>mid<69><64><EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD>
|
||||
uint64_t mid; //ǰ<>˷<EFBFBD><CBB7>͵Ľ<CDB5>ĿID
|
||||
uint64_t* pid; //PID_MAXNUM, need when media_json
|
||||
int64_t create_time;
|
||||
int64_t renew_time;
|
||||
int64_t lastpkt_time;
|
||||
int64_t dedup_query_time;
|
||||
|
||||
char td[TD_LEN];
|
||||
char* td_data;
|
||||
uint32_t td_datalen;
|
||||
uint32_t addrlist_len; //for app
|
||||
char* addrlist;
|
||||
|
||||
opt_in_t* opt[MEDIA_OPT_MAXNUN][OPT_MAXNUN];
|
||||
int opt_index;
|
||||
int url_opt_index; //<2F><><EFBFBD><EFBFBD>url<72><6C><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
|
||||
struct qw_queue query_wait_lq; //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ض<EFBFBD>Դ<EFBFBD><D4B4>ѯ<EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||
MESA_timer_index_t* timer_idx;
|
||||
MESA_timer_index_t* index_query_timer_idx;
|
||||
|
||||
uint64_t byte_in;
|
||||
uint64_t byte_proc;
|
||||
uint32_t pkt_in;
|
||||
uint32_t pkt_proc;
|
||||
|
||||
uint64_t maxoffset;
|
||||
uint64_t media_len; //from more frag_unit
|
||||
|
||||
#if K_PROJECT
|
||||
int hit_service; //monitor flag
|
||||
#else
|
||||
uint8_t hit_service; //monitor flag
|
||||
uint8_t pad[3]; //monitor flag
|
||||
#endif
|
||||
uint8_t proto; //from data, from frag_unit
|
||||
uint8_t media_type; //from media_info, from frag_unit
|
||||
uint8_t data_flag; //monitor flag
|
||||
int8_t meta_flag;
|
||||
|
||||
int8_t flag; // PROG_FLAG_EXCP PROG_FLAG_DUMP
|
||||
uint8_t qdinfo_idx_last;
|
||||
uint8_t pid_idx_last;
|
||||
uint8_t repeat_reoffset_idx_last;
|
||||
|
||||
uint64_t acc_offset; //HLS acc offset
|
||||
int64_t repeat_reoffset[KEEP_REOFFSET_MAXNUM]; //HLS reoffset that have proc,<2C><><EFBFBD>ౣ<EFBFBD><E0B1A3>KEEP_REOFFSET_MAXNUM<55><4D>Ƭ<EFBFBD><C6AC><EFBFBD>ظ<EFBFBD><D8B8>Ľ<EFBFBD><C4BD><EFBFBD>ȥ<EFBFBD><C8A5>
|
||||
|
||||
qd_info_t qd_info[QD_MAXNUM]; //<2F><><EFBFBD><EFBFBD>ǰ<EFBFBD>˻<EFBFBD><CBBB><EFBFBD><EFBFBD><EFBFBD>mid<69><64>capIP<49><50>Ӧ<EFBFBD><D3A6>ϵ
|
||||
qd_info_t qd_info_from_cpz[QD_MAXNUM]; //<2F><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴװ<C6B4><D7B0>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>Ϣ
|
||||
|
||||
uint32_t frag_unit_cnt; //for pid
|
||||
uint32_t configID;
|
||||
uint32_t multisrc_bizmanip;
|
||||
int thread_seq; //the first frag_unit thread_seq
|
||||
|
||||
char wins_dest_disabled_bit; //stop send to subsystem,equal to MAX_EXCP_PORT
|
||||
uint8_t media_service_type; //HLS or OSMF... SIP AV
|
||||
int8_t td_query; //0:init
|
||||
int8_t cache_flag;
|
||||
uint8_t td_complete; //0:init
|
||||
uint8_t qdinfo_from_cpz_idx_last;
|
||||
|
||||
uint8_t sip_survey_type; //SIP_SURVEY_TYPE_FD SIP_SURVEY_TYPE_JC SIP_SURVEY_TYPE_FD_JC
|
||||
//uint8_t sip_sendlog_flag;
|
||||
opt_in_t* sip_opt[SIP_OPT_NUM]; //opttype is fulllog type
|
||||
opt_in_t* sip_rate_info;
|
||||
opt_in_t* sip_diadata_ID;
|
||||
uint64_t re_offset;
|
||||
char* fd_buf;
|
||||
char* jc_buf;
|
||||
uint32_t fd_buflen;
|
||||
uint32_t jc_buflen;
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
int64_t survey_time;
|
||||
uint32_t cfg_id; //config ID
|
||||
uint8_t service;
|
||||
char level; //the level of check result
|
||||
char log_url[512];
|
||||
char* monitor_path;
|
||||
//char frag_bitmap[KEEP_REOFFSET_MAXNUM/8+1]; //bitmap for frag removal
|
||||
}media_t;
|
||||
|
||||
/*recv : add_media_info for cnvg_hash*/
|
||||
typedef struct rssb_media_info_s
|
||||
{
|
||||
uint64_t pid;
|
||||
uint64_t media_len;
|
||||
char* opt;
|
||||
|
||||
int opt_num;
|
||||
int thread_seq;
|
||||
|
||||
uint32_t cap_IP;
|
||||
uint32_t src_ip;
|
||||
|
||||
#if K_PROJECT
|
||||
int hitservice;
|
||||
#else
|
||||
uint8_t hitservice;
|
||||
uint8_t pad[3];
|
||||
#endif
|
||||
uint8_t media_type;
|
||||
uint8_t protocol;
|
||||
uint8_t data_flag;
|
||||
int8_t flag;
|
||||
}rssb_media_info_t;
|
||||
|
||||
typedef struct frag_reassembly_s
|
||||
{
|
||||
void* sifter;
|
||||
void* logger;
|
||||
void* media_logger;
|
||||
|
||||
MESA_htable_handle converge_hash; /*frag <20><>Ƭ<EFBFBD>ỰHASH*/
|
||||
|
||||
MESA_lqueue_head* wait_lq;
|
||||
|
||||
uint16_t lq_num;
|
||||
uint16_t logger_level;
|
||||
|
||||
uint32_t cnvg_hash_thread_safe;
|
||||
uint32_t cnvg_hash_size;
|
||||
uint32_t cnvg_hash_max_elem_num;
|
||||
uint32_t cnvg_hash_expire_time;
|
||||
|
||||
/*stat**/
|
||||
uint32_t sysinfo_interval;
|
||||
uint32_t stat_interval;
|
||||
|
||||
void* sysinfo_handle;
|
||||
void* stat_handle;
|
||||
|
||||
/*sysinfo*/
|
||||
uint64_t stat_info[RSSB_LOG_TYPE_MAXNUM];
|
||||
uint64_t data_info[RSSB_DATALOG_TYPE_MAXNUM][LOG_STAT_MAXNUM];
|
||||
uint64_t sysinfo_stat[RSSB_SYSLOG_TYPE_MAXNUM][SYSLOG_STAT_MAXNUM];
|
||||
|
||||
int log_field_id[RSSB_LOG_TYPE_MAXNUM];
|
||||
int datalog_column_id[LOG_STAT_MAXNUM];
|
||||
int datalog_line_id[RSSB_DATALOG_TYPE_MAXNUM];
|
||||
int syslog_column_id[SYSLOG_STAT_MAXNUM];
|
||||
int syslog_line_id[RSSB_SYSLOG_TYPE_MAXNUM];
|
||||
|
||||
/*redis*/
|
||||
struct timeval redis_tv;
|
||||
char redis_addr[20480];
|
||||
redisClusterContext* redis_cluster_ctx[MAX_THREAD_NUM];
|
||||
redisContext* redis_ctx[MAX_THREAD_NUM];
|
||||
int redis_cluster_switch;
|
||||
char redis_ip[32];
|
||||
int redis_port;
|
||||
|
||||
uint32_t wait_lq_num;
|
||||
}frag_reassembly_t;
|
||||
|
||||
/*printaddr <20><>ʽ, used in app*/
|
||||
typedef struct __touple4_type
|
||||
{
|
||||
char sip[64];
|
||||
char dip[64];
|
||||
unsigned short sport;
|
||||
unsigned short dport;
|
||||
int addr_type;
|
||||
}touple4_type_t;
|
||||
|
||||
#define FRAG_CONTAIN_MAXNUM 8 //ȥ<><C8A5>:<3A><>ȫ<EFBFBD><C8AB><EFBFBD>ǵ<EFBFBD>frag<61><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>
|
||||
/*for create_media because IVI */
|
||||
typedef struct frag_ivi_info_s
|
||||
{
|
||||
frag_unit_t* frg_unit;
|
||||
frag_in_t* frg;
|
||||
//query_detail_t* query_detail;
|
||||
frag_in_t* frg_array[FRAG_CONTAIN_MAXNUM];//frag<61><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȥ<CEAA>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>frag
|
||||
//char td_result[TD_LEN];
|
||||
uint64_t mid;
|
||||
int frg_array_cnt;
|
||||
uint8_t td_query; //TD_QUERY_TYPE_MULTISRC TD_QUERY_TYPE_DEDUP
|
||||
uint8_t thread_seq; //for av dedup
|
||||
}frag_ivi_info_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int frag_add_wait_lq(frag_ivi_info_t* frag_ivi_info, uint32_t frag_stat, int thread_seq);
|
||||
void init_frag_unit(frag_unit_t* frg_unit, uchar protocol);
|
||||
int media_create(frag_unit_t* frg_unit);
|
||||
int frag_service(frag_ivi_info_t* frag_ivi_info, uint32_t src_ip, int thread_seq);
|
||||
void free_opt(opt_in_t** data);
|
||||
void free_text(text_t** pp, int n_p);
|
||||
int free_frag_in(void *data, long data_len, void *arg);
|
||||
uint64_t make_mid(char * key, unsigned int size, unsigned char type);
|
||||
void free_frag_unit(void* data);
|
||||
void free_media(void* data);
|
||||
int expire_media_hash_node(void *data, int eliminate_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
255
src/frag_recv.c
Normal file
255
src/frag_recv.c
Normal file
@@ -0,0 +1,255 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "AV_interface.h"
|
||||
#include "frag_reassembly.h"
|
||||
#include "frag_recv.h"
|
||||
#include "my_socket.h"
|
||||
#include "bizman.h"
|
||||
#include "log.h"
|
||||
#include "frag_voip.h"
|
||||
#include "wiredLB.h"
|
||||
#include "service.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
|
||||
void heart_beat(unsigned int thread_id,char *buf, uint32_t size, uint32_t src_ip)
|
||||
{
|
||||
msg_header_t *mh = (msg_header_t*)buf;
|
||||
mh->msg_type = MSG_LIVE_RESPONS;
|
||||
bizman_send(g_frag_run.answer_sapp_bizman, thread_id, src_ip, g_frag_cfg.msg_port, (const char*)buf, size, 1, BIZMAN_SMOOTH_DEST|BIZMAN_PUSH_SEND);
|
||||
}
|
||||
|
||||
void proc_data_msg(uint32_t thread_id, uint32_t src_ip, char* packet, int size)
|
||||
{
|
||||
msg_header_t* mhead = (msg_header_t*)packet;
|
||||
msg_metainfo_t* minfo = (msg_metainfo_t*)(packet + MSG_HEADER_LEN);
|
||||
msg_data_t* mdata = (msg_data_t*)(packet + MSG_HEADER_LEN);
|
||||
char* data = (char*)mdata + MSG_DATA_HEAD_LEN;
|
||||
char* opt_ptr = NULL;
|
||||
|
||||
/* Ignore invalid packet */
|
||||
if(PROTO_MAGICNUM != mhead->magic_num || PROTO_VERSION != mhead->version|| size <= (int)MSG_HEADER_LEN || size>1600)
|
||||
{
|
||||
atomic_inc(&g_frag_stat.stat_info[INVALID_RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[INVALID_RECV][TOTAL_BYTES],size);
|
||||
return;
|
||||
}
|
||||
/*prco msg*/
|
||||
switch(mhead->msg_type)
|
||||
{
|
||||
case MSG_DATA_META:
|
||||
/*write log*/
|
||||
if(RLOG_LV_INFO>=g_frag_run.frag_loglevel)
|
||||
{
|
||||
int buf_len = 32;
|
||||
char pbuf[32] = {0};
|
||||
char qbuf[32] = {0};
|
||||
inet_ntop(AF_INET, &src_ip, pbuf, buf_len);
|
||||
inet_ntop(AF_INET, &minfo->cap_IP, qbuf, buf_len);
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} %s:%hd RECV META [PID:%llu, media_len:%llu, media_type:0x%02x, cap_IP:%s]",
|
||||
__FILE__,__LINE__, pbuf, g_frag_cfg.bizman_port, *(uint64_t*)minfo->prog_id, minfo->prog_len, minfo->media_type, qbuf);
|
||||
}
|
||||
/*avoid uncomplete chunk*/
|
||||
if(mhead->cont_len-MSG_HEADER_LEN>2000) return;
|
||||
/*for frag_reassembly*/
|
||||
opt_ptr = packet + MSG_HEADER_LEN + sizeof(msg_metainfo_t);
|
||||
if(g_frag_cfg.all_hit_monitor_switch==ALL_HIT_MONITOR_SWITCH)
|
||||
{
|
||||
#if K_PROJECT
|
||||
minfo->hitservice = 0x181;
|
||||
#else
|
||||
minfo->hitservice = 0x81;
|
||||
#endif
|
||||
minfo->data_flag = 4;
|
||||
}
|
||||
add_media_info(minfo, opt_ptr, src_ip, thread_id);
|
||||
atomic_inc(&g_frag_stat.stat_info[META_RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[META_RECV][TOTAL_BYTES],size);
|
||||
break;
|
||||
|
||||
case MSG_DATA_BODY:
|
||||
case MSG_DATA_TAIL:
|
||||
/*write log*/
|
||||
if(RLOG_LV_DEBUG>=g_frag_run.frag_loglevel)
|
||||
{
|
||||
int buf_len = 32;
|
||||
char pbuf[32] = {0};
|
||||
inet_ntop(AF_INET, &src_ip, pbuf, buf_len);
|
||||
/*<2A><>ӡVOIP<49><50><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>SEQ*/
|
||||
if(g_frag_cfg.cpz_type==CPZ_VOIP)
|
||||
{
|
||||
int rtp_seq = ntohl(*(int*)(data+VOIP_DATA_SEQ_OFFSET));
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_DEBUG, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} %s:%hd RECV DATA [PID:%llu, offset:%llu, rtp_seq:%d, datalen:%u]",
|
||||
__FILE__,__LINE__, pbuf, g_frag_cfg.bizman_port, *(uint64_t*)mdata->prog_id, mdata->offset, rtp_seq, mhead->cont_len-MSG_DATA_HEAD_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_DEBUG, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} %s:%hd RECV DATA [PID:%llu, offset:%llu, datalen:%u]",
|
||||
__FILE__,__LINE__, pbuf, g_frag_cfg.bizman_port, *(uint64_t*)mdata->prog_id, mdata->offset, mhead->cont_len-MSG_DATA_HEAD_LEN);
|
||||
}
|
||||
}
|
||||
/*??? protocol lost debug for uncomplete chunk*/
|
||||
if(mhead->cont_len-MSG_DATA_HEAD_LEN>2000) return;
|
||||
if(mdata->offset>1000000000000) return;
|
||||
/*for frag_reassembly*/
|
||||
add_frag(*(uint64_t*)mdata->prog_id,mdata->offset,data,mhead->cont_len-MSG_DATA_HEAD_LEN,0,src_ip,thread_id);
|
||||
atomic_inc(&g_frag_stat.stat_info[DATA_RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[DATA_RECV][TOTAL_BYTES],size);
|
||||
break;
|
||||
|
||||
case MSG_LIVE_CHECK:
|
||||
heart_beat(thread_id, packet, size, src_ip);
|
||||
break;
|
||||
|
||||
default:
|
||||
atomic_inc(&g_frag_stat.stat_info[OTHER_RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[OTHER_RECV][TOTAL_BYTES],size);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void free_recv_data(bizman_recv_data_t* recv_data)
|
||||
{
|
||||
if(NULL!=recv_data)
|
||||
{
|
||||
if(NULL!=recv_data->data)
|
||||
{
|
||||
free(recv_data->data);
|
||||
recv_data->data = NULL;
|
||||
}
|
||||
free(recv_data);
|
||||
}
|
||||
}
|
||||
|
||||
void* bizman_recv_data_from_queue(void *param)
|
||||
{
|
||||
long tid = (long)param;
|
||||
bizman_recv_data_t* recv_data = NULL;
|
||||
long recv_data_size = sizeof(recv_data);
|
||||
|
||||
while(1)
|
||||
{
|
||||
recv_data = NULL;
|
||||
int rec = MESA_lqueue_get_head(g_frag_run.recv_bizman_lq[tid], &recv_data, &recv_data_size);
|
||||
if (rec<0)
|
||||
{
|
||||
usleep(10);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL!=recv_data && NULL!=recv_data->data)
|
||||
{
|
||||
/*get from queue stat */
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[BIZMAN_RECV_QUEUE][QUEUE_OUT]);
|
||||
proc_data_msg(tid, recv_data->src_ip, recv_data->data, recv_data->size);
|
||||
}
|
||||
free_recv_data(recv_data);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* bizman_recv_data_to_queue(void *param)
|
||||
{
|
||||
char buf[BIZMAN_RECV_BUFFSIZE] = {0};
|
||||
int size = 0;
|
||||
uint32_t src_ip = 0;
|
||||
uint16_t src_port = 0;
|
||||
uint32_t is_complete = 0, stream_id = 0;
|
||||
long tid = (long)param;
|
||||
int lq_rec = 0;
|
||||
bizman_recv_data_t* recv_data = NULL;
|
||||
|
||||
while(1)
|
||||
{
|
||||
size = bizman_recv(g_frag_run.recv_bizman[tid],(char*)buf,sizeof(buf),&src_ip,&src_port,&stream_id,&is_complete);
|
||||
if(is_complete&BIZMAN_READ_CHUNK && size>0)
|
||||
{
|
||||
if(g_frag_stat.sysinfo_stat[BIZMAN_RECV_QUEUE][QUEUE_CURRENT]<g_frag_cfg.bizman_queue_maxnum)
|
||||
{
|
||||
recv_data = (bizman_recv_data_t*)calloc(1, sizeof(bizman_recv_data_t));
|
||||
recv_data->size = size;
|
||||
recv_data->src_ip = src_ip;
|
||||
recv_data->data = (char*)malloc(size);
|
||||
memcpy(recv_data->data, buf, size);
|
||||
/*data[15] = the last byte of PID*/
|
||||
tid = recv_data->data[15]%g_frag_cfg.thread_num;
|
||||
lq_rec = MESA_lqueue_join_tail(g_frag_run.recv_bizman_lq[tid], &recv_data, sizeof(recv_data));
|
||||
if(lq_rec==MESA_QUEUE_RET_OK)
|
||||
{
|
||||
/*add to queue stat */
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[BIZMAN_RECV_QUEUE][QUEUE_IN]);
|
||||
}
|
||||
else
|
||||
{
|
||||
free_recv_data(recv_data);
|
||||
atomic_inc(&g_frag_stat.stat_info[RECV_DROP][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[RECV_DROP][TOTAL_BYTES], size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
atomic_inc(&g_frag_stat.stat_info[RECV_DROP][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[RECV_DROP][TOTAL_BYTES], size);
|
||||
}
|
||||
atomic_inc(&g_frag_stat.stat_info[RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[RECV][TOTAL_BYTES], size);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* bizman_recv_data(void *param)
|
||||
{
|
||||
long tid = (long)param;
|
||||
char buf[BIZMAN_RECV_BUFFSIZE] = {0};
|
||||
int size = 0;
|
||||
uint32_t src_ip = 0;
|
||||
uint16_t src_port = 0;
|
||||
uint32_t is_complete = 0, stream_id = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
size = bizman_recv(g_frag_run.recv_bizman[tid],(char*)buf,sizeof(buf),&src_ip,&src_port,&stream_id,&is_complete);
|
||||
if(is_complete&BIZMAN_READ_CHUNK && size>0)
|
||||
{
|
||||
proc_data_msg(tid, src_ip, buf, size);
|
||||
atomic_inc(&g_frag_stat.stat_info[RECV][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[RECV][TOTAL_BYTES], size);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* wlb_report(void *param)
|
||||
{
|
||||
uint64_t start_bytes = g_frag_stat.stat_info[RECV][TOTAL_BYTES];
|
||||
uint64_t start_pkts = g_frag_stat.stat_info[RECV][TOTAL_PKTS];
|
||||
while(1)
|
||||
{
|
||||
wiredLB_report(g_frag_cfg.rssb_wlb_handle, g_frag_stat.stat_info[RECV][TOTAL_BYTES] - start_bytes,g_frag_stat.stat_info[RECV][TOTAL_PKTS]- start_pkts, "I am fine!");
|
||||
start_bytes = g_frag_stat.stat_info[RECV][TOTAL_BYTES];
|
||||
start_pkts = g_frag_stat.stat_info[RECV][TOTAL_PKTS];
|
||||
sleep(g_frag_cfg.wlb_report_interval);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
28
src/frag_recv.h
Normal file
28
src/frag_recv.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _FRAG_RECV_H
|
||||
#define _FRAG_RECV_H
|
||||
|
||||
/*from preproc*/
|
||||
#define BIZMAN_RECV_BUFFSIZE (1024+512)
|
||||
|
||||
typedef struct bizman_recv_data_s
|
||||
{
|
||||
int size;
|
||||
uint32_t src_ip;
|
||||
char* data;
|
||||
}bizman_recv_data_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void* bizman_recv_data_from_queue(void *param);
|
||||
void* bizman_recv_data_to_queue(void *param);
|
||||
void* bizman_recv_data(void *param);
|
||||
void* wlb_report(void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
181
src/frag_redis.c
Normal file
181
src/frag_redis.c
Normal file
@@ -0,0 +1,181 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hiredis.h"
|
||||
#include "hircluster.h"
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
#include "frag_redis.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
extern frag_reassembly_t frag_rssb; //use media hash
|
||||
|
||||
/*
|
||||
<EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD> Ϊ<><CEAA>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><E1B9A9>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ϣ,<2C><><EFBFBD><EFBFBD>redis<69><73>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cc: <09><>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
flag<61><67> <09>Ӽ<EFBFBD>Ⱥ<EFBFBD><C8BA>ΨһIP<49>α<EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>涨<EFBFBD><E6B6A8><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>ѡһ
|
||||
uni_ipfrag: ΨһIP<49>εľ<CEB5><C4BE><EFBFBD>ֵ
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>0 <20>ɹ<EFBFBD>
|
||||
-1 ʧ<><CAA7>
|
||||
*/
|
||||
extern "C" int redisClusterEnableSalve(redisClusterContext *cc, int flag, const char *uni_ipfrag);
|
||||
|
||||
/**
|
||||
*
|
||||
*return :
|
||||
* -1:connect error;
|
||||
* -2:reply error(need to freeReplyObject) ;
|
||||
* 0:succ(need to freeReplyObject)
|
||||
*/
|
||||
int redis_nocluster_excute_command(int thread_seq, void* logger, redisReply** reply, char* cmmd, int argc, const char **argv, const size_t *argvlen)
|
||||
{
|
||||
int rec = 0;
|
||||
redisReply* cmmd_reply = *reply;
|
||||
|
||||
if(NULL==frag_rssb.redis_ctx[thread_seq] || frag_rssb.redis_ctx[thread_seq]->err)
|
||||
{
|
||||
if(NULL!=frag_rssb.redis_ctx[thread_seq])
|
||||
{
|
||||
redisFree(frag_rssb.redis_ctx[thread_seq]);
|
||||
frag_rssb.redis_ctx[thread_seq] = NULL;
|
||||
}
|
||||
frag_rssb.redis_ctx[thread_seq] = redisConnectWithTimeout(frag_rssb.redis_ip, frag_rssb.redis_port, frag_rssb.redis_tv);
|
||||
}
|
||||
if(NULL==frag_rssb.redis_ctx[thread_seq]) return -1;
|
||||
|
||||
if(frag_rssb.redis_ctx[thread_seq]->err)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis exec command '%s' fail, connect error:%s].",
|
||||
__FILE__,__LINE__, cmmd, frag_rssb.redis_ctx[thread_seq]->errstr);
|
||||
redisFree(frag_rssb.redis_ctx[thread_seq]);
|
||||
frag_rssb.redis_ctx[thread_seq] = NULL;
|
||||
rec = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//cmmd_reply = (redisReply *)redisCommand(frag_rssb.redis_ctx[thread_seq], cmmd);
|
||||
cmmd_reply = (redisReply *)redisCommandArgv(frag_rssb.redis_ctx[thread_seq], argc, argv, argvlen);
|
||||
/*replyΪNULL<4C><4C><EFBFBD><EFBFBD>ʾ<EFBFBD>ͻ<EFBFBD><CDBB>˺ͷ<CBBA><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><F3A3ACB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
if(NULL==cmmd_reply)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis exec command '%s' fail, connect error:%s].",
|
||||
__FILE__,__LINE__, cmmd, frag_rssb.redis_ctx[thread_seq]->errstr);
|
||||
redisFree(frag_rssb.redis_ctx[thread_seq]);
|
||||
frag_rssb.redis_ctx[thread_seq] = NULL;
|
||||
freeReplyObject(cmmd_reply);
|
||||
rec = -2;
|
||||
}
|
||||
else if(cmmd_reply->type==REDIS_REPLY_ERROR)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis exec command '%s' fail, reply error:%s].",
|
||||
__FILE__,__LINE__, cmmd, cmmd_reply->str);
|
||||
freeReplyObject(cmmd_reply);
|
||||
rec = -2;
|
||||
}
|
||||
}
|
||||
|
||||
if(0==rec)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis exec command '%s' succ].",
|
||||
__FILE__,__LINE__, cmmd);
|
||||
}
|
||||
*reply = cmmd_reply;
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*return :
|
||||
* -1:connect error;
|
||||
* -2:reply error(need to freeReplyObject) ;
|
||||
* 0:succ(need to freeReplyObject)
|
||||
*/
|
||||
int redis_cluster_excute_command(int thread_seq, void* logger, redisReply** reply, char* cmmd, int argc, const char **argv, const size_t *argvlen)
|
||||
{
|
||||
int rec = 0;
|
||||
redisReply* cmmd_reply = *reply;
|
||||
|
||||
if(NULL==frag_rssb.redis_cluster_ctx[thread_seq] || frag_rssb.redis_cluster_ctx[thread_seq]->err)
|
||||
{
|
||||
if(NULL!=frag_rssb.redis_cluster_ctx[thread_seq])
|
||||
{
|
||||
redisClusterFree(frag_rssb.redis_cluster_ctx[thread_seq]);
|
||||
frag_rssb.redis_cluster_ctx[thread_seq] = NULL;
|
||||
}
|
||||
frag_rssb.redis_cluster_ctx[thread_seq] = redisClusterConnectWithTimeout(frag_rssb.redis_addr, frag_rssb.redis_tv, HIRCLUSTER_FLAG_NULL);
|
||||
//redisClusterEnableSalve(frag_rssb.redis_cluster_ctx[thread_seq], frag_rssb.redis_cluster_netflag, frag_rssb.redis_cluster_net);
|
||||
}
|
||||
if(NULL==frag_rssb.redis_cluster_ctx[thread_seq]) return -1;
|
||||
|
||||
if(frag_rssb.redis_cluster_ctx[thread_seq]->err)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis cluster exec command '%s' fail, connect error:%s].",
|
||||
__FILE__,__LINE__, cmmd, frag_rssb.redis_cluster_ctx[thread_seq]->errstr);
|
||||
redisClusterFree(frag_rssb.redis_cluster_ctx[thread_seq]);
|
||||
frag_rssb.redis_cluster_ctx[thread_seq] = NULL;
|
||||
rec = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//cmmd_reply = (redisReply *)redisClusterCommand(frag_rssb.redis_cluster_ctx[thread_seq], cmmd);
|
||||
cmmd_reply = (redisReply *)redisClusterCommandArgv(frag_rssb.redis_cluster_ctx[thread_seq], argc, argv, argvlen);
|
||||
/*replyΪNULL<4C><4C><EFBFBD><EFBFBD>ʾ<EFBFBD>ͻ<EFBFBD><CDBB>˺ͷ<CBBA><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><F3A3ACB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
if(NULL==cmmd_reply)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis cluster exec command '%s' fail, connect error:%s].",
|
||||
__FILE__,__LINE__, cmmd, frag_rssb.redis_cluster_ctx[thread_seq]->errstr);
|
||||
redisClusterFree(frag_rssb.redis_cluster_ctx[thread_seq]);
|
||||
frag_rssb.redis_cluster_ctx[thread_seq] = NULL;
|
||||
freeReplyObject(cmmd_reply);
|
||||
rec = -2;
|
||||
}
|
||||
else if(cmmd_reply->type==REDIS_REPLY_ERROR)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis cluster exec command '%s' fail, reply error:%s].",
|
||||
__FILE__,__LINE__, cmmd, cmmd_reply->str);
|
||||
freeReplyObject(cmmd_reply);
|
||||
rec = -2;
|
||||
}
|
||||
}
|
||||
|
||||
if(0==rec)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} [redis cluster exec command '%s' succ].",
|
||||
__FILE__,__LINE__, cmmd);
|
||||
}
|
||||
*reply = cmmd_reply;
|
||||
return rec;
|
||||
}
|
||||
|
||||
int redis_excute_command(int thread_seq, void* logger, redisReply** reply, char* cmmd, int argc, const char **argv, const size_t *argvlen)
|
||||
{
|
||||
if(frag_rssb.redis_cluster_switch==1)
|
||||
{
|
||||
return redis_cluster_excute_command(thread_seq, logger, reply, cmmd, argc, argv, argvlen);
|
||||
}
|
||||
else if(frag_rssb.redis_cluster_switch==2)
|
||||
{
|
||||
return redis_nocluster_excute_command(thread_seq, logger, reply, cmmd, argc, argv, argvlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
15
src/frag_redis.h
Normal file
15
src/frag_redis.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _FRAG_REDIS_H
|
||||
#define _FRAG_REDIS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int redis_excute_command(int thread_seq, void* logger, redisReply** reply, char* cmmd, int argc, const char **argv, const size_t *argvlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
753
src/frag_send.c
Normal file
753
src/frag_send.c
Normal file
@@ -0,0 +1,753 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
#include "bizman.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "frag_reassembly.h"
|
||||
#include "AV_interface.h"
|
||||
#include "AV_sendback.h"
|
||||
#include "AV_sendback_in.h"
|
||||
#include "my_socket.h"
|
||||
#include "common.h"
|
||||
#include "service.h"
|
||||
#include "usm_api.h"
|
||||
#include "frag_proc.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
extern frag_reassembly_t frag_rssb;
|
||||
|
||||
extern "C" void* frag_forward(void *param);
|
||||
|
||||
msg_map_t g_av_mediatype_map[AV_MEDAI_TYPE_MAXNUM] =
|
||||
{
|
||||
{FILE_UNKNOWN, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_VIDEO, MEDIA_TYPE_VIDEO},
|
||||
{FILE_WMV, MEDIA_TYPE_WMV},
|
||||
{FILE_MPG, MEDIA_TYPE_MPG},
|
||||
{FILE_FLV, MEDIA_TYPE_FLV},
|
||||
{FILE_RMFF, MEDIA_TYPE_RMFF},
|
||||
{FILE_AVI, MEDIA_TYPE_AVI},
|
||||
{FILE_SWF, MEDIA_TYPE_SWF},
|
||||
{FILE_MPG4, MEDIA_TYPE_MPG4},
|
||||
{FILE_AIFF, MEDIA_TYPE_AIFF},
|
||||
{FILE_OGG, MEDIA_TYPE_OGG},
|
||||
{FILE_DRC, MEDIA_TYPE_DRC},
|
||||
{FILE_DIRECTSHOW, MEDIA_TYPE_DIRECTSHOW},
|
||||
|
||||
{FILE_FLIC, MEDIA_TYPE_FLIC},
|
||||
{FILE_INDEO, MEDIA_TYPE_INDEO},
|
||||
{FILE_MKV, MEDIA_TYPE_MKV},
|
||||
{FILE_AUDIO, MEDIA_TYPE_AUDIO},
|
||||
{FILE_MP3, MEDIA_TYPE_MP3},
|
||||
{FILE_OSMF, MEDIA_TYPE_OSMF},
|
||||
{FILE_HLS, MEDIA_TYPE_HLS},
|
||||
{FILE_IOS, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_ANDRIOD, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_APP, MEDIA_TYPE_UNKNOWN},
|
||||
|
||||
{AUDIO_UNKNOWN, MEDIA_TYPE_AUDIO_UNKNOWN},
|
||||
{AUDIO_G711_ULAW, MEDIA_TYPE_AUDIO_G711_ULAW},
|
||||
{AUDIO_G711_ALAW, MEDIA_TYPE_AUDIO_G711_ALAW},
|
||||
{AUDIO_G722, MEDIA_TYPE_AUDIO_G722},
|
||||
{AUDIO_G723, MEDIA_TYPE_AUDIO_G723},
|
||||
{AUDIO_G726_40, MEDIA_TYPE_AUDIO_G726_40},
|
||||
{AUDIO_G726_32, MEDIA_TYPE_AUDIO_G726_32},
|
||||
{AUDIO_G726_24, MEDIA_TYPE_AUDIO_G726_24},
|
||||
{AUDIO_G726_16, MEDIA_TYPE_AUDIO_G726_16},
|
||||
{AUDIO_AAL2_G726_40, MEDIA_TYPE_AUDIO_AAL2_G726_40},
|
||||
{AUDIO_AAL2_G726_32, MEDIA_TYPE_AUDIO_AAL2_G726_32},
|
||||
{AUDIO_AAL2_G726_24, MEDIA_TYPE_AUDIO_AAL2_G726_24},
|
||||
{AUDIO_AAL2_G726_16, MEDIA_TYPE_AUDIO_AAL2_G726_16},
|
||||
{AUDIO_G728, MEDIA_TYPE_AUDIO_G728},
|
||||
{AUDIO_G729D, MEDIA_TYPE_AUDIO_G729D},
|
||||
{AUDIO_G729E, MEDIA_TYPE_AUDIO_G729E},
|
||||
{AUDIO_GSM, MEDIA_TYPE_AUDIO_GSM},
|
||||
{AUDIO_GSM_EFR, MEDIA_TYPE_AUDIO_GSM_EFR},
|
||||
{AUDIO_ILBC, MEDIA_TYPE_AUDIO_ILBC},
|
||||
{AUDIO_AMR, MEDIA_TYPE_AUDIO_AMR},
|
||||
{AUDIO_AMR_WB, MEDIA_TYPE_AUDIO_AMR_WB},
|
||||
{AUDIO_SILK, MEDIA_TYPE_AUDIO_SILK},
|
||||
{AUDIO_LPC, MEDIA_TYPE_AUDIO_LPC},
|
||||
{AUDIO_LPC1016, MEDIA_TYPE_AUDIO_LPC1016},
|
||||
{AUDIO_LPC1015, MEDIA_TYPE_AUDIO_LPC1015},
|
||||
{AUDIO_L16, MEDIA_TYPE_AUDIO_L16},
|
||||
{AUDIO_SPEEX, MEDIA_TYPE_AUDIO_SPEEX},
|
||||
{AUDIO_L8, MEDIA_TYPE_AUDIO_L8},
|
||||
{AUDIO_MPA, MEDIA_TYPE_AUDIO_MPA},
|
||||
{AUDIO_DVI4, MEDIA_TYPE_AUDIO_DVI4},
|
||||
{AUDIO_VDVI, MEDIA_TYPE_AUDIO_VDVI},
|
||||
{AUDIO_CN, MEDIA_TYPE_AUDIO_CN},
|
||||
{AUDIO_RED, MEDIA_TYPE_AUDIO_RED},
|
||||
{AUDIO_QCELP, MEDIA_TYPE_AUDIO_QCELP},
|
||||
{AUDIO_EVRC0, MEDIA_TYPE_AUDIO_EVRC0},
|
||||
{AUDIO_EVRCB0, MEDIA_TYPE_AUDIO_EVRCB0},
|
||||
{AUDIO_G729, MEDIA_TYPE_AUDIO_G729},
|
||||
{AUDIO_VIVOX, MEDIA_TYPE_AUDIO_VIVOX},
|
||||
|
||||
{FILE_IMAGE, MEDIA_TYPE_IMAGE},
|
||||
{FILE_JPG, MEDIA_TYPE_JPG},
|
||||
{FILE_BMP, MEDIA_TYPE_BMP},
|
||||
{FILE_GIF, MEDIA_TYPE_GIF},
|
||||
|
||||
{MMS_TYPE, MEDIA_TYPE_MMS},
|
||||
{RTSP_RDT_TYPE, MEDIA_TYPE_RTSP_RDT},
|
||||
{RTSP_RTP_TYPE, MEDIA_TYPE_RTSP_RTP}
|
||||
};
|
||||
|
||||
/*
|
||||
msg_map_t g_av_mediatype_map[AV_MEDAI_TYPE_MAXNUM] =
|
||||
{
|
||||
{FILE_UNKNOWN, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_VIDEO, MEDIA_TYPE_VIDEO},
|
||||
{FILE_WMV, MEDIA_TYPE_WMV},
|
||||
{FILE_MPG, MEDIA_TYPE_MPG},
|
||||
{FILE_FLV, MEDIA_TYPE_FLV},
|
||||
{FILE_RMFF, MEDIA_TYPE_RMFF},
|
||||
{FILE_AVI, MEDIA_TYPE_AVI},
|
||||
{FILE_SWF, MEDIA_TYPE_SWF},
|
||||
{FILE_MPG4, MEDIA_TYPE_MPG4},
|
||||
{FILE_AIFF, MEDIA_TYPE_AIFF},
|
||||
{FILE_OGG, MEDIA_TYPE_OGG},
|
||||
{FILE_DRC, MEDIA_TYPE_DRC},
|
||||
{FILE_DIRECTSHOW, MEDIA_TYPE_DIRECTSHOW},
|
||||
|
||||
{FILE_FLIC, MEDIA_TYPE_FLIC},
|
||||
{FILE_INDEO, MEDIA_TYPE_INDEO},
|
||||
{FILE_MKV, MEDIA_TYPE_MKV},
|
||||
{FILE_AUDIO, MEDIA_TYPE_AUDIO},
|
||||
{FILE_MP3, MEDIA_TYPE_MP3},
|
||||
{FILE_OSMF, MEDIA_TYPE_OSMF},
|
||||
{FILE_HLS, MEDIA_TYPE_HLS},
|
||||
{FILE_IOS, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_ANDRIOD, MEDIA_TYPE_UNKNOWN},
|
||||
{FILE_APP, MEDIA_TYPE_UNKNOWN},
|
||||
|
||||
{AUDIO_UNKNOWN, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G711_ULAW, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G711_ALAW, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G722, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G723, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G726_40, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G726_32, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G726_24, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G726_16, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_AAL2_G726_40, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_AAL2_G726_32, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_AAL2_G726_16, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G728, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G729D, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G729E, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_GSM, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_GSM_EFR, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_ILBC, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_AMR, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_AMR_WB, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_SILK, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_LPC, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_LPC1016, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_LPC1015, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_L16, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_SPEEX, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_L8, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_MPA, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_DVI4, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_VDVI, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_CN, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_RED, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_QCELP, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_EVRC0, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_EVRCB0, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_G729, MEDIA_TYPE_VOIP},
|
||||
{AUDIO_VIVOX, MEDIA_TYPE_VOIP},
|
||||
|
||||
{FILE_IMAGE, MEDIA_TYPE_IMAGE},
|
||||
{FILE_JPG, MEDIA_TYPE_JPG},
|
||||
{FILE_BMP, MEDIA_TYPE_BMP},
|
||||
{FILE_GIF, MEDIA_TYPE_GIF},
|
||||
|
||||
{MMS_TYPE, MEDIA_TYPE_MMS},
|
||||
{HTTP_STREAM_TYPE, MEDIA_TYPE_HTTP_STREAM},
|
||||
{RTSP_RDT_TYPE, MEDIA_TYPE_RTSP_RDT},
|
||||
{RTSP_RTP_TYPE, MEDIA_TYPE_RTSP_RTP}
|
||||
};
|
||||
*/
|
||||
|
||||
msg_map_t g_av_proto_map[AV_PROTO_MAXNUM] =
|
||||
{
|
||||
{AV_PROTOCOL_HTTP, PROTOCOL_HTTP},
|
||||
{AV_PROTOCOL_SMTP, PROTOCOL_SMTP},
|
||||
{AV_PROTOCOL_POP3, PROTOCOL_POP3},
|
||||
{AV_PROTOCOL_IMAP, PROTOCOL_IMAP},
|
||||
{AV_PROTOCOL_FTP, PROTOCOL_FTP},
|
||||
{AV_PROTOCOL_HTTP_STREAM, PROTOCOL_HTTP_PIC},
|
||||
{AV_PROTOCOL_RTSP_RDT, PROTOCOL_RTSP_RDT},
|
||||
{AV_PROTOCOL_RTSP_RTP, PROTOCOL_RTSP_RTP},
|
||||
{AV_PROTOCOL_MMS, PROTOCOL_MMS},
|
||||
{AV_PROTOCOL_RTMP, PROTOCOL_RTMP},
|
||||
{AV_PROTOCOL_SIP, PROTOCOL_SIP},
|
||||
};
|
||||
|
||||
void send_data_by_udp(const char* data, uint32_t datalen, int thread_id)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int send_rec = 0;
|
||||
|
||||
atomic_inc(&g_frag_stat.stat_info[SRC_WINS_SEND][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[SRC_WINS_SEND][TOTAL_BYTES], datalen);
|
||||
for(i=0;i<g_frag_cfg.send_dest_udp_ip_num;i++)
|
||||
{
|
||||
send_rec = send_udp_socket_send(g_frag_run.send_sd[thread_id],
|
||||
g_frag_cfg.send_dest_udp_iplist[i],
|
||||
g_frag_cfg.send_dest_udp_port[i],
|
||||
(char*)data,datalen);
|
||||
if(-1==send_rec)
|
||||
{
|
||||
/*static output*/
|
||||
atomic_inc(&g_frag_stat.send_stat[i][FAIL_PKTS]);
|
||||
atomic_add(&g_frag_stat.send_stat[i][FAIL_BYTES], datalen);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/*static output*/
|
||||
atomic_inc(&g_frag_stat.send_stat[i][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.send_stat[i][TOTAL_BYTES], datalen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_data_by_unixsocket(const char* data, uint32_t datalen, int thread_id)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int send_rec = 0;
|
||||
// send data to linux backend
|
||||
if(0<g_frag_cfg.send_dest_addr_num)
|
||||
{
|
||||
//static output
|
||||
atomic_inc(&g_frag_stat.stat_info[SRC_SEND_LOCAL][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[SRC_SEND_LOCAL][TOTAL_BYTES], datalen);
|
||||
for(i=0;i<g_frag_cfg.send_dest_addr_num;i++)
|
||||
{
|
||||
send_rec = unix_socket_send(g_frag_run.send_fd[thread_id],&g_frag_cfg.send_dest_addr[i],data,datalen);
|
||||
|
||||
if(-1==send_rec)
|
||||
{
|
||||
//static output
|
||||
atomic_inc(&g_frag_stat.send_stat[i][FAIL_PKTS]);
|
||||
atomic_add(&g_frag_stat.send_stat[i][FAIL_BYTES], datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
//static output
|
||||
atomic_inc(&g_frag_stat.send_stat[i][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.send_stat[i][TOTAL_BYTES], datalen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_data(const char* data, uint32_t datalen, int thread_id)
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD>UDP<44>ش<EFBFBD>*/
|
||||
#if K_PROJECT
|
||||
send_data_by_udp(data, datalen, thread_id);
|
||||
/*<2A><><EFBFBD><EFBFBD>unix socket<65>ش<EFBFBD>*/
|
||||
#else
|
||||
send_data_by_unixsocket(data, datalen, thread_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
void send_data_bizman(const char* data, uint32_t datalen, uint64_t mid,uint32_t ip, int thread_id)
|
||||
{
|
||||
atomic_inc(&g_frag_stat.stat_info[SRC_SEND_CPZ][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[SRC_SEND_CPZ][TOTAL_BYTES], datalen);
|
||||
int i = mid%g_frag_cfg.thread_num;
|
||||
bizman_send(g_frag_run.cpz_send_bizman,
|
||||
thread_id,
|
||||
ip,
|
||||
g_frag_cfg.bizman_port+i,
|
||||
data,
|
||||
datalen,
|
||||
1,BIZMAN_RELIABLE_SEND|BIZMAN_SMOOTH_DEST|BIZMAN_PUSH_SEND);
|
||||
}
|
||||
|
||||
void send_data_usm(const char* data, uint32_t datalen, int thread_id)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int send_rec = 0;
|
||||
/* send data to linux backend*/
|
||||
if(0<g_frag_cfg.send_dest_addr_num)
|
||||
{
|
||||
/*static output*/
|
||||
atomic_inc(&g_frag_stat.stat_info[SRC_SEND_LOCAL][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[SRC_SEND_LOCAL][TOTAL_BYTES], datalen);
|
||||
|
||||
send_rec = USM_write(g_frag_run.a_usm_handle,data,datalen);
|
||||
|
||||
for(i=0;i<g_frag_cfg.send_dest_addr_num;i++)
|
||||
{
|
||||
g_frag_stat.send_stat[i][TOTAL_PKTS] = USM_stat(g_frag_run.a_usm_handle,READED_CNT,i);
|
||||
g_frag_stat.send_stat[i][TOTAL_BYTES] = USM_stat(g_frag_run.a_usm_handle,READED_SIZE,i);
|
||||
g_frag_stat.send_stat[i][FAIL_PKTS] = USM_stat(g_frag_run.a_usm_handle,READER_DROP_CNT,i);
|
||||
g_frag_stat.send_stat[i][FAIL_BYTES] = USM_stat(g_frag_run.a_usm_handle,READER_DROP_SIZE,i);
|
||||
g_frag_stat.send_lq_stat[i][TOTAL_PKTS] = USM_stat(g_frag_run.a_usm_handle,LQ_COUNT,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long check_sendto_wins_cb(void *data, const uint8_t *key, uint size, void *user_arg)
|
||||
{
|
||||
media_t* mdi = (media_t*)data;
|
||||
|
||||
if(NULL!=mdi)
|
||||
{
|
||||
*(char*)user_arg = mdi->wins_dest_disabled_bit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_sendto_wins(uint64_t mid, char* wins_dest_disabled_bit)
|
||||
{
|
||||
long rec_cb = 0;
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t*)&mid, sizeof(mid),
|
||||
check_sendto_wins_cb, wins_dest_disabled_bit, &rec_cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_data_to_wins(uint64_t mid, const char* data, uint32_t datalen, int thread_id)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int send_rec = 0;
|
||||
uint32_t sendip = g_frag_cfg.special_media_wins_ip[mid % g_frag_cfg.special_media_wins_ip_num];
|
||||
char wins_dest_disabled_bit = 0;
|
||||
char wins_dest_disabled_flag[DEST_MAXNUM] = {0};
|
||||
|
||||
check_sendto_wins(mid, &wins_dest_disabled_bit);
|
||||
if(FLAG_TEST(wins_dest_disabled_bit, AUDIO_WINS_DISABLE))
|
||||
{
|
||||
wins_dest_disabled_flag[0] = 1;
|
||||
}
|
||||
if(FLAG_TEST(wins_dest_disabled_bit, VEDIO_WINS_DISABLE))
|
||||
{
|
||||
wins_dest_disabled_flag[2] = 1;
|
||||
}
|
||||
/* send data to windows backend*/
|
||||
if(g_frag_cfg.special_media_wins_port_num)
|
||||
{
|
||||
atomic_inc(&g_frag_stat.stat_info[SRC_WINS_SEND][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[SRC_WINS_SEND][TOTAL_BYTES], datalen);
|
||||
for(i=0;i<g_frag_cfg.special_media_wins_port_num;i++)
|
||||
{
|
||||
if(wins_dest_disabled_flag[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
send_rec = send_udp_socket_send(g_frag_run.send_windows_sd[thread_id],
|
||||
sendip,g_frag_cfg.special_media_wins_port[i],
|
||||
(char*)data,datalen);
|
||||
if(-1==send_rec)
|
||||
{
|
||||
/*static output*/
|
||||
atomic_inc(&g_frag_stat.wins_send_stat[i][FAIL_PKTS]);
|
||||
atomic_add(&g_frag_stat.wins_send_stat[i][FAIL_BYTES], datalen);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/*static output*/
|
||||
atomic_inc(&g_frag_stat.wins_send_stat[i][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.wins_send_stat[i][TOTAL_BYTES], datalen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pack_and_send_data(frag_in_t* frg, int thread_id)
|
||||
{
|
||||
msg_head_t* msghead = NULL;
|
||||
av_data_t* msgdata = NULL;
|
||||
char* sendbuf = NULL;
|
||||
int sendbuflen = 0;
|
||||
|
||||
/*calculate sendbuflen*/
|
||||
sendbuflen = sizeof(msg_head_t)+sizeof(av_data_t)+frg->datalen;
|
||||
sendbuf = (char*)malloc(sendbuflen);
|
||||
memset(sendbuf, 0, sendbuflen);
|
||||
|
||||
/*set msg header*/
|
||||
msghead = (msg_head_t*)sendbuf;
|
||||
msghead->magic = AV_MAGIC_VALUE;
|
||||
msghead->m_type = AV_TYPE_DATA;
|
||||
msghead->c_len = sizeof(av_data_t)+frg->datalen;
|
||||
|
||||
/*set msg data*/
|
||||
msgdata = (av_data_t*)(sendbuf + sizeof(msg_head_t));
|
||||
memcpy(msgdata->pid, &frg->mid, sizeof(frg->mid));
|
||||
msgdata->frag_seq = frg->seq;
|
||||
msgdata->offset = frg->offset;
|
||||
|
||||
/*send data*/
|
||||
memcpy(sendbuf+sizeof(msg_head_t)+sizeof(av_data_t), frg->data, frg->datalen);
|
||||
|
||||
if(FLAG_TEST(frg->frag_flag, FRAG_FLAG_MULTISRC))
|
||||
{
|
||||
send_data_bizman(sendbuf, sendbuflen, frg->mid, frg->multisrc_bizmanip, thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_frag_run.usm_on_flag)
|
||||
{
|
||||
send_data_usm(sendbuf,sendbuflen,thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_data(sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
if(g_frag_cfg.special_media_fwd_switch && FLAG_TEST(frg->frag_flag, FRAG_FLAG_WINS))
|
||||
{
|
||||
send_data_to_wins(frg->mid, sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
}
|
||||
/*free*/
|
||||
if(NULL!=sendbuf)
|
||||
{
|
||||
free(sendbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void pack_and_send_frag(frag_in_t* frg, int thread_id)
|
||||
{
|
||||
msg_header_t* msghead = NULL;
|
||||
msg_data_t* msgdata = NULL;
|
||||
char* sendbuf = NULL;
|
||||
int sendbuflen = 0;
|
||||
|
||||
/*calculate sendbuflen*/
|
||||
sendbuflen = sizeof(msg_header_t)+sizeof(msg_data_t)+frg->datalen;
|
||||
sendbuf = (char*)malloc(sendbuflen);
|
||||
memset(sendbuf, 0, sendbuflen);
|
||||
|
||||
/*set msg header*/
|
||||
msghead = (msg_header_t*)sendbuf;
|
||||
msghead->magic_num = PROTO_MAGICNUM;
|
||||
msghead->version = PROTO_VERSION;
|
||||
msghead->msg_type = MSG_DATA_BODY;
|
||||
msghead->cont_len = MSG_DATA_HEAD_LEN+frg->datalen;
|
||||
|
||||
/*set msg data*/
|
||||
msgdata = (msg_data_t*)(sendbuf + MSG_HEADER_LEN);
|
||||
memcpy(msgdata->prog_id, &frg->mid, sizeof(frg->mid));
|
||||
msgdata->offset = frg->offset;
|
||||
msgdata->frag_seq = frg->seq;
|
||||
|
||||
/*send data*/
|
||||
memcpy(sendbuf+MSG_HEADER_LEN+MSG_DATA_HEAD_LEN, frg->data, frg->datalen);
|
||||
|
||||
if(FLAG_TEST(frg->frag_flag, FRAG_FLAG_MULTISRC))
|
||||
{
|
||||
send_data_bizman(sendbuf, sendbuflen, frg->mid, frg->multisrc_bizmanip, thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_frag_run.usm_on_flag)
|
||||
{
|
||||
send_data_usm(sendbuf,sendbuflen,thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_data(sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
if(g_frag_cfg.special_media_fwd_switch && FLAG_TEST(frg->frag_flag, FRAG_FLAG_WINS))
|
||||
{
|
||||
send_data_to_wins(frg->mid, sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
}
|
||||
/*free*/
|
||||
if(NULL!=sendbuf)
|
||||
{
|
||||
free(sendbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void send_frag(frag_in_t* frg, int thread_id)
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD>AV_sendback.h<><68><EFBFBD><EFBFBD><EFBFBD>Ļش<C4BB><D8B4>ӿ<EFBFBD>*/
|
||||
#if K_PROJECT
|
||||
pack_and_send_data(frg, thread_id);
|
||||
/*<2A><><EFBFBD><EFBFBD>AV_interface.h<><68><EFBFBD><EFBFBD><EFBFBD>Ļش<C4BB><D8B4>ӿ<EFBFBD>*/
|
||||
#else
|
||||
pack_and_send_frag(frg, thread_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t msg_convertion(uint8_t src, msg_map_t* map_list, int list_size)
|
||||
{
|
||||
for(int i=0;i<list_size;i++)
|
||||
{
|
||||
if(src==map_list[i].nodeA)
|
||||
{
|
||||
return map_list[i].nodeB;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pack_and_send_meta_info(media_info_t* media_info, frag_in_t* frg, int thread_id)
|
||||
{
|
||||
msg_head_t* msghead = NULL;
|
||||
msg_meta_t* msginfo = NULL;
|
||||
char* sendbuf = NULL;
|
||||
int sendbuflen = 0;
|
||||
char* ptr = NULL;
|
||||
int opt_len = 0;
|
||||
|
||||
/*calculate sendbuflen*/
|
||||
sendbuflen = sizeof(msg_head_t)+sizeof(msg_meta_t);
|
||||
|
||||
/*calculate opts len*/
|
||||
for(int i=0;i<media_info->opt_num;i++)
|
||||
{
|
||||
sendbuflen += media_info->opt_unit[i].opt_len;
|
||||
opt_len += media_info->opt_unit[i].opt_len;
|
||||
}
|
||||
|
||||
/*get mem*/
|
||||
sendbuf = (char*)malloc(sendbuflen);
|
||||
memset(sendbuf, 0, sendbuflen);
|
||||
|
||||
/*set msg header*/
|
||||
msghead = (msg_head_t*)sendbuf;
|
||||
msghead->magic = AV_MAGIC_VALUE;
|
||||
msghead->m_type = AV_TYPE_META;
|
||||
msghead->c_len = sizeof(msg_meta_t);
|
||||
|
||||
/*set msg media info*/
|
||||
msginfo = (msg_meta_t*)(sendbuf + sizeof(msg_head_t));
|
||||
memcpy(msginfo->pid, &media_info->mid, sizeof(media_info->mid));
|
||||
msginfo->proglen = media_info->prog_len;
|
||||
msginfo->capip = media_info->cap_IP;
|
||||
msginfo->data_flag = media_info->data_flag;
|
||||
/*Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽṹ<D6BD><E1B9B9>֮<EFBFBD><D6AE>ת<EFBFBD><D7AA>av_interface->av_sendback*/
|
||||
msginfo->protocol = msg_convertion(media_info->protocol, g_av_proto_map, AV_PROTO_MAXNUM);
|
||||
/*ý<><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽṹ<D6BD><E1B9B9>֮<EFBFBD><D6AE>ת<EFBFBD><D7AA>av_interface->av_sendback*/
|
||||
msginfo->mediatype = msg_convertion(media_info->media_type, g_av_mediatype_map, AV_MEDAI_TYPE_MAXNUM);
|
||||
|
||||
/*opt*/
|
||||
msginfo->opt_num = media_info->opt_num;
|
||||
ptr = sendbuf + sizeof(msg_head_t)+sizeof(msg_meta_t);
|
||||
for(int i=0;i<media_info->opt_num;i++)
|
||||
{
|
||||
*(unsigned int *)ptr = media_info->opt_unit[i].opt_len;
|
||||
ptr += sizeof(unsigned int);
|
||||
*(unsigned char *)ptr = media_info->opt_unit[i].opt_type;
|
||||
ptr += sizeof(unsigned char);
|
||||
memcpy(ptr, media_info->opt_unit[i].opt_value, media_info->opt_unit[i].opt_len-sizeof(uint8_t)-sizeof(uint32_t));
|
||||
ptr += media_info->opt_unit[i].opt_len-sizeof(uint8_t)-sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/*send data*/
|
||||
if(FLAG_TEST(frg->frag_flag, FRAG_FLAG_MULTISRC))
|
||||
{
|
||||
send_data_bizman(sendbuf, sendbuflen, media_info->mid, frg->multisrc_bizmanip, thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_frag_run.usm_on_flag)
|
||||
{
|
||||
send_data_usm(sendbuf,sendbuflen,thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_data(sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
if(g_frag_cfg.special_media_fwd_switch && FLAG_TEST(frg->frag_flag, FRAG_FLAG_WINS))
|
||||
{
|
||||
send_data_to_wins(frg->mid, sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
}
|
||||
/*free*/
|
||||
if(NULL!=sendbuf)
|
||||
{
|
||||
free(sendbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void pack_and_send_media_info(media_info_t* media_info, frag_in_t* frg, int thread_id)
|
||||
{
|
||||
msg_header_t* msghead = NULL;
|
||||
msg_metainfo_t* msginfo = NULL;
|
||||
char* ptr = NULL;
|
||||
char* sendbuf = NULL;
|
||||
int sendbuflen = 0;
|
||||
int i=0;
|
||||
int opt_len = 0;
|
||||
|
||||
/*calculate sendbuflen*/
|
||||
sendbuflen = sizeof(msg_header_t)+sizeof(msg_metainfo_t);
|
||||
|
||||
/*calculate opts len*/
|
||||
for(i=0;i<media_info->opt_num;i++)
|
||||
{
|
||||
sendbuflen += media_info->opt_unit[i].opt_len;
|
||||
opt_len += media_info->opt_unit[i].opt_len;
|
||||
}
|
||||
|
||||
/*get mem*/
|
||||
sendbuf = (char*)malloc(sendbuflen);
|
||||
memset(sendbuf, 0, sendbuflen);
|
||||
|
||||
/*set msg header*/
|
||||
msghead = (msg_header_t*)sendbuf;
|
||||
msghead->magic_num = PROTO_MAGICNUM;
|
||||
msghead->version = PROTO_VERSION;
|
||||
msghead->msg_type = MSG_DATA_META;
|
||||
msghead->cont_len = MSG_MEDIAINFO_HEAD_LEN+opt_len;
|
||||
|
||||
/*set msg media info*/
|
||||
msginfo = (msg_metainfo_t*)(sendbuf + MSG_HEADER_LEN);
|
||||
memcpy(msginfo->prog_id, &media_info->mid, sizeof(media_info->mid));
|
||||
msginfo->prog_len = media_info->prog_len;
|
||||
msginfo->hitservice = media_info->hitservice;
|
||||
msginfo->cap_IP = media_info->cap_IP;
|
||||
msginfo->protocol = media_info->protocol;
|
||||
msginfo->media_type = media_info->media_type;
|
||||
msginfo->data_flag = media_info->data_flag;
|
||||
msginfo->flag = media_info->flag;
|
||||
msginfo->opt_num = media_info->opt_num;
|
||||
|
||||
ptr = sendbuf + sizeof(msg_header_t) + sizeof(msg_metainfo_t);
|
||||
for(i=0;i<media_info->opt_num;i++)
|
||||
{
|
||||
*(unsigned int *)ptr = media_info->opt_unit[i].opt_len;
|
||||
ptr += sizeof(unsigned int);
|
||||
*(unsigned char *)ptr = media_info->opt_unit[i].opt_type;
|
||||
ptr += sizeof(unsigned char);
|
||||
memcpy(ptr, media_info->opt_unit[i].opt_value, media_info->opt_unit[i].opt_len-sizeof(uint8_t)-sizeof(uint32_t));
|
||||
ptr += media_info->opt_unit[i].opt_len-sizeof(uint8_t)-sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/*send data*/
|
||||
if(FLAG_TEST(frg->frag_flag, FRAG_FLAG_MULTISRC))
|
||||
{
|
||||
send_data_bizman(sendbuf, sendbuflen, media_info->mid, frg->multisrc_bizmanip, thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_frag_run.usm_on_flag)
|
||||
{
|
||||
send_data_usm(sendbuf,sendbuflen,thread_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_data(sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
if(g_frag_cfg.special_media_fwd_switch && FLAG_TEST(frg->frag_flag, FRAG_FLAG_WINS))
|
||||
{
|
||||
send_data_to_wins(frg->mid, sendbuf, sendbuflen, thread_id);
|
||||
}
|
||||
}
|
||||
/*free*/
|
||||
if(NULL!=sendbuf)
|
||||
{
|
||||
free(sendbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void send_media_info(media_info_t* media_info, frag_in_t* frg, int thread_id)
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD>AV_sendback.h<><68><EFBFBD><EFBFBD><EFBFBD>Ļش<C4BB><D8B4>ӿ<EFBFBD>*/
|
||||
#if K_PROJECT
|
||||
pack_and_send_meta_info(media_info, frg, thread_id);
|
||||
#else
|
||||
/*<2A><><EFBFBD><EFBFBD>AV_interface.h<><68><EFBFBD><EFBFBD><EFBFBD>Ļش<C4BB><D8B4>ӿ<EFBFBD>*/
|
||||
pack_and_send_media_info(media_info, frg, thread_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* frag_forward(void *param)
|
||||
{
|
||||
long thread_seq = (long)param;
|
||||
frag_in_t* frg_in = NULL;
|
||||
long frglen = sizeof(frg_in);
|
||||
media_info_t media_info;
|
||||
long rec_cb = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int rec = MESA_lqueue_get_head(frag_rssb.wait_lq[thread_seq], &frg_in, &frglen);
|
||||
if (rec<0)
|
||||
{
|
||||
usleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&media_info,0,sizeof(media_info_t));
|
||||
if(FLAG_TEST(frg_in->frag_flag, FRAG_FLAG_SEND_META))
|
||||
{
|
||||
/*borrow only*/
|
||||
media_info.prog_len = frg_in->datalen;
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t *)&frg_in->mid,sizeof(frg_in->mid),
|
||||
get_media, (void*)&media_info, &rec_cb);
|
||||
/*<2A><>Դ<EFBFBD><D4B4>ʹ<EFBFBD>þɵ<C3BE>mid<69><64>ѯ<EFBFBD><D1AF>Ŀ<EFBFBD><C4BF>Ϣ*/
|
||||
/*
|
||||
if(FLAG_TEST(frg_in->frag_flag, FRAG_FLAG_MULTISRC))
|
||||
{
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t *)&frg_in->old_mid,sizeof(frg_in->old_mid),
|
||||
get_media, (void*)&media_info, &rec_cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_htable_search_cb(g_frag_run.media_hash, (const uint8_t *)&frg_in->mid,sizeof(frg_in->mid),
|
||||
get_media, (void*)&media_info, &rec_cb);
|
||||
}
|
||||
*/
|
||||
if(rec_cb)
|
||||
{
|
||||
frag_write_to_log(GET_META, media_info.mid, &media_info, NULL, 0);
|
||||
send_media_info(&media_info, frg_in, thread_seq);
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} SEND META [MID:%llu, proto:%hu, media_len:%llu, media_type:0x%02x]",
|
||||
__FILE__,__LINE__, media_info.mid, media_info.protocol, media_info.prog_len, media_info.media_type);
|
||||
atomic_inc(&g_frag_stat.media_stat[LOG_MEDIA_OUTPUT]);
|
||||
/*free mediainfo opt , this is not good free outside*/
|
||||
if(NULL!=media_info.opt_unit)
|
||||
{
|
||||
for(int i=0;i<media_info.opt_num;i++)
|
||||
{
|
||||
if(NULL!=media_info.opt_unit[i].opt_value)
|
||||
{
|
||||
free(media_info.opt_unit[i].opt_value);
|
||||
media_info.opt_unit[i].opt_value = NULL;
|
||||
}
|
||||
}
|
||||
free(media_info.opt_unit);
|
||||
media_info.opt_unit = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*<2A><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD>Ҫ<EFBFBD><EFBFBD>midΪ<64>µ<EFBFBD>mid*/
|
||||
frg_in->mid = frg_in->new_mid;
|
||||
send_frag(frg_in, thread_seq);
|
||||
frag_write_to_log(GET_FRAG, frg_in->mid, frg_in, NULL, 0);
|
||||
atomic_inc(&frag_rssb.sysinfo_stat[RSSB_WAIT_QUEUE][QUEUE_OUT]);
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_DEBUG, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} SEND DATA [MID:%llu, PID:%llu, seq:%u, offset:%llu, datalen:%u]",
|
||||
__FILE__,__LINE__, frg_in->mid, frg_in->pid, frg_in->seq, frg_in->offset, frg_in->datalen);
|
||||
free_frag_in(frg_in, 0, NULL);
|
||||
frg_in = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
23
src/frag_send.h
Normal file
23
src/frag_send.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _FRAG_SEND_H
|
||||
#define _FRAG_SEND_H
|
||||
|
||||
/*ͨ<><CDA8>sokcet<65>ӿڷ<D3BF><DAB7>ͱ<EFBFBD><CDB1><EFBFBD>*/
|
||||
#define FRAG_SEND_SOCKET 0x01
|
||||
/*<2A><>Դͨ<D4B4><CDA8>bizman<61><6E><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD>frag_rssb*/
|
||||
#define FRAG_SEND_BIZMAN 0x02
|
||||
/*<2A>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ʧ*/
|
||||
#define FRAG_SEND_DROP 0x03
|
||||
|
||||
/*<2A><>Դ<EFBFBD>ۺϵĵ<CFB5>ַ*/
|
||||
#define MEDIA_SEND_DST_LOCAL 0x00 /*<2A><><EFBFBD><EFBFBD>*/
|
||||
#define MEDIA_SEND_DST_OTHER 0x01 /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴװ*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1051
src/frag_voip.c
Normal file
1051
src/frag_voip.c
Normal file
File diff suppressed because it is too large
Load Diff
156
src/frag_voip.h
Normal file
156
src/frag_voip.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef _VOIP_REASSEMBLY_H
|
||||
#define _VOIP_REASSEMBLY_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
/*index in g_sip_opt_type*/
|
||||
#define SIP_CALL_ID_OPT_INDEX 11
|
||||
#define SIP_FROM_TAGS_OPT_INDEX 9
|
||||
#define SIP_TO_TAGS_OPT_INDEX 10
|
||||
#define SIP_RESCODE_OPT_INDEX 30
|
||||
#define SIP_REASON_OPT_INDEX 22
|
||||
#define SIP_CSEQ_OPT_INDEX 12
|
||||
#define SIP_USERAGENT_OPT_INDEX 15
|
||||
#define SIP_URI_OPT_INDEX 1
|
||||
#define SIP_C_CONTACT_OPT_INDEX 13
|
||||
#define SIP_S_CONTACT_OPT_INDEX 14
|
||||
#define SIP_C_VIA_OPT_INDEX 27
|
||||
#define SIP_S_VIA_OPT_INDEX 24
|
||||
#define SIP_C_RECORD_ROUTES_OPT_INDEX 28
|
||||
#define SIP_S_RECORD_ROUTES_OPT_INDEX 25
|
||||
#define SIP_C_ROUTE_OPT_INDEX 29
|
||||
#define SIP_S_ROUTE_OPT_INDEX 26
|
||||
#define SIP_C_CODING_OPT_INDEX 8
|
||||
#define SIP_S_CODING_OPT_INDEX 7
|
||||
#define SIP_FROM_OPT_INDEX 2
|
||||
#define SIP_TO_OPT_INDEX 3
|
||||
#define SIP_RTP_4TUPLE_OPT_INDEX 0
|
||||
#define SIP_SIP_4TUPLE_OPT_INDEX 23
|
||||
#define SIP_DURATION_OPT_INDEX 6
|
||||
|
||||
#define SIP_PROTO_SIP "SIP-RTP"
|
||||
#define SIP_PROTO_RTP "RTP"
|
||||
#define SIP_METHOD_OPT "INVITE"
|
||||
#define SIP_PROTO_OPT "SIP"
|
||||
|
||||
/*ȫ<><C8AB><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define SIP_OPT_MAXNUM 16
|
||||
/*voip<69><70>־<EFBFBD><D6BE>Ϣͷsip_log_msg_header_t*/
|
||||
#define SIP_LOG_CONT_CODE_NOTHING 0
|
||||
#define SIP_LOG_VERSION 3
|
||||
#define SIP_FULLLOG_MAGIC_NUM 0x5632
|
||||
#define SIP_FULLLOG_CONT_CODE_VERSION 0X03
|
||||
#define SIP_FULLLOG_MSG_TYPE 0x21
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>Ϣͷsip_og_msg_header_t*/
|
||||
#define SIP_SURVEYLOG_MAGIC_NUM 0x5641
|
||||
#define SIP_SURVEYLOG_MSG_TYPE 0x21
|
||||
|
||||
/*ȫ<><C8AB><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>g_sip_opt_type*/
|
||||
#define OPT_VOIP_PID 0x29
|
||||
#define OPT_VOIP_DUATION_FULLLOG 0x2A
|
||||
#define OPT_VOIP_VOICE_DIR_FULLLOG 0x2B
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ѡ<D6BE><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define OPT_LAYER_ADDR_V4 0x3B //0x3B:RTP, 0x2D:SIP, change
|
||||
#define OPT_VOIP_RECV_TIME 0x2F
|
||||
#define OPT_VOIP_DUATION 0x30
|
||||
#define OPT_VOIP_PROTOCOL 0x31
|
||||
#define OPT_VOIP_CALLING_ACCOUNT 0x32
|
||||
#define OPT_VOIP_CALLED_ACCOUNT 0x33
|
||||
#define OPT_VOIP_RELATION_RTP_LAYER_ADDR_V4 0x2D //0x3B:RTP, 0x2D:SIP, change
|
||||
#define OPT_VOIP_FROM_TO_STORE_IP 0x36
|
||||
#define OPT_VOIP_FROM_TO_STORE_URL 0x37
|
||||
#define OPT_VOIP_TO_FROM_STORE_IP 0x38
|
||||
#define OPT_VOIP_TO_FROM_STORE_URL 0x39
|
||||
|
||||
/*sip_sendlog_flag*/
|
||||
#define SIP_SEND_FULL_LOG 0x01
|
||||
#define SIP_SEND_SURVEY_LOG 0x02
|
||||
|
||||
/*sip<69><70>ѯʹ<D1AF><CAB9>key1 key2 key3*/
|
||||
#define SIP_KEY_1 1
|
||||
#define SIP_KEY_2 2
|
||||
#define SIP_KEY_3 3
|
||||
|
||||
/*RTP<54><50><EFBFBD><EFBFBD>ǰ8<C7B0><38><EFBFBD>ֽڣ<D6BD>4<EFBFBD><34><EFBFBD>ֽڵ<D6BD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>ֽڵ<D6BD>rtp_seq*/
|
||||
#define VOIP_DATA_SEQ_OFFSET 4
|
||||
#define VOIP_DATA_TIME_SEQ_LEN 8
|
||||
|
||||
typedef struct sip_fulllog_msg_body_s
|
||||
{
|
||||
char call_id[128]; // not NULL
|
||||
char from_tags[64];
|
||||
char to_tags[64];
|
||||
char version[16];
|
||||
char method[16];
|
||||
char status[8]; //?? rescode not exist
|
||||
char reason[128];
|
||||
char cseq[128];
|
||||
char src_ip[20];
|
||||
uint32_t src_port;
|
||||
char dst_ip[20];
|
||||
uint32_t dst_port;
|
||||
char useragent[128];
|
||||
char from_rtp_ip[20];
|
||||
uint32_t from_rtp_port;
|
||||
char to_rtp_ip[20];
|
||||
uint32_t to_rtp_port;
|
||||
uint32_t paw_num; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1>ţ<EFBFBD><C5A3><EFBFBD>ʱΪ0
|
||||
char cly_ip[20]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP<49><50><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>дΪ<D0B4><CEAA>ƿװIP
|
||||
time_t found_time;
|
||||
uint16_t opt_num; //ѡ<><D1A1><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>
|
||||
}__attribute__((packed))sip_fulllog_msg_body_t;
|
||||
|
||||
typedef struct sip_surveylog_msg_body_s
|
||||
{
|
||||
unsigned long long prog_id; // <20><>Ŀ<EFBFBD><C4BF>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
uint32_t cfg_id; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
|
||||
uint32_t found_time; // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
uint32_t cap_ip; // Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP<49><50>ַ
|
||||
uint8_t protocol; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
|
||||
uint8_t service; // ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t level; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
||||
uint8_t fd_type; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint16_t opt_num; //ѡ<><D1A1><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>
|
||||
//struct opt_unit_t opt_info[opt_num]; //ѡ<><D1A1><EFBFBD><EFBFBD>Ϣ,<2C><><EFBFBD><EFBFBD>ʾ<EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>
|
||||
}__attribute__((packed))sip_surveylog_msg_body_t;
|
||||
|
||||
typedef struct sip_log_msg_header_s
|
||||
{
|
||||
uint16_t magic_num; // ħ<><C4A7><EFBFBD><EFBFBD>survey logֵ<67><D6B5><EFBFBD><EFBFBD>Ϊ0x5641 ; fulllogֵ<67><D6B5><EFBFBD><EFBFBD>Ϊ0x5632
|
||||
uint8_t cont_code:4; // <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||
uint8_t version:4; // Э<><D0AD><EFBFBD>汾<EFBFBD><E6B1BE>Ŀǰֵ<C7B0><D6B5>3
|
||||
uint8_t msg_type; // <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
||||
uint32_t cont_len; // <20><>Ϣ<EFBFBD>岿<EFBFBD>ֵ<EFBFBD><D6B5>ֽڳ<D6BD><DAB3><EFBFBD>
|
||||
}sip_log_msg_header_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void free_media_sip(media_t* mdi);
|
||||
void free_frag_unit_sip_opt(frag_unit_t* frg_unit);
|
||||
|
||||
|
||||
int redis_sip_index_query(frag_unit_t* frg_unit, int thread_seq);
|
||||
int sip_index_query(frag_unit_t* frg_unit, int thread_seq);
|
||||
|
||||
|
||||
int sip_send_full_log(media_t* mdi);
|
||||
int sip_send_survey_log(media_t* mdi, char* survey, uint32_t survey_len);
|
||||
void send_sip_log_when_expire(media_t* mdi);
|
||||
|
||||
void proc_sip_opt(frag_unit_t* frg_unit, media_t* mdi);
|
||||
int proc_sip_mediainfo_opt(frag_unit_t* frg_unit, rssb_media_info_t* media_info);
|
||||
|
||||
|
||||
void set_frag_unit_from_media(media_t* mdi, frag_unit_t* frg_unit);
|
||||
void set_sip_frag_unit(rssb_media_info_t* media_info, frag_unit_t* frg_unit);
|
||||
int parse_sip_4tuple(char* str_4tuple,char* s_ip,char* s_port,char* c_ip,char* c_port);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
181
src/hard_keepalive.c
Normal file
181
src/hard_keepalive.c
Normal file
@@ -0,0 +1,181 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/un.h>
|
||||
#include <stddef.h>//offsetof
|
||||
|
||||
#include "hard_keepalive.h"
|
||||
|
||||
int udp_socket_recv(int sockfd, uint32_t *src_ip, uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
if (NULL == buf) return -1;
|
||||
|
||||
int numbytes;
|
||||
struct sockaddr_storage their_addr;
|
||||
socklen_t addr_len = sizeof(their_addr);
|
||||
|
||||
if ((numbytes = recvfrom(sockfd, buf, buf_size , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1)
|
||||
{
|
||||
perror("recvfrom");
|
||||
return -1;
|
||||
}
|
||||
*src_ip = ((struct sockaddr_in *)&their_addr)->sin_addr.s_addr;
|
||||
return numbytes;
|
||||
}
|
||||
|
||||
// send udp packet
|
||||
int udp_socket_send(int sockfd, uint32_t addr, uint16_t port, char *data, int datalen)
|
||||
{
|
||||
struct sockaddr_in dst_addr; /* connector's address information */
|
||||
dst_addr.sin_family = AF_INET; /* host byte order */
|
||||
dst_addr.sin_port = port; /* short, network byte order */
|
||||
dst_addr.sin_addr.s_addr = addr;
|
||||
bzero(&(dst_addr.sin_zero), 8); /* zero the rest of the struct */
|
||||
int to_send_len=datalen;
|
||||
int already_sended_len=0;
|
||||
while(to_send_len>0)
|
||||
{
|
||||
already_sended_len=sendto(sockfd,data,
|
||||
to_send_len-already_sended_len,
|
||||
0,
|
||||
(struct sockaddr *)&(dst_addr),
|
||||
sizeof(dst_addr));
|
||||
if(already_sended_len==-1)
|
||||
{
|
||||
if((EAGAIN == errno)||( EINTR == errno )|| (EWOULDBLOCK==errno))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
to_send_len-=already_sended_len;
|
||||
}
|
||||
return already_sended_len;
|
||||
}
|
||||
|
||||
int create_recv_udp_socket(uint16_t port)
|
||||
{
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (-1 == sockfd)
|
||||
{
|
||||
perror("listener: socket");
|
||||
return -1;
|
||||
}
|
||||
struct sockaddr_in my_addr; /* my address information */
|
||||
my_addr.sin_family = AF_INET; /* host byte order */
|
||||
my_addr.sin_port = port; /* short, network byte order */
|
||||
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
|
||||
bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */
|
||||
|
||||
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
perror("listener: bind");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
|
||||
int create_send_udp_socket()
|
||||
{
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (-1 == sockfd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void* thread_hard_keepalive(void *param)
|
||||
{
|
||||
char buf[1500] = {0};
|
||||
long port = (long)param;
|
||||
int size = 0;
|
||||
uint32_t src_ip = 0;
|
||||
int send_rec = 0;
|
||||
fd_set rset;
|
||||
int recv_pkt_sd = create_recv_udp_socket(htons(port));
|
||||
int send_pkt_sd = create_send_udp_socket();
|
||||
|
||||
if(-1==recv_pkt_sd || -1==send_pkt_sd)
|
||||
{
|
||||
printf("hard_keepalive create socket error.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(recv_pkt_sd,&rset);
|
||||
if(-1==select(recv_pkt_sd+1,&rset,NULL,NULL,NULL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(FD_ISSET(recv_pkt_sd, &rset))
|
||||
{
|
||||
size = udp_socket_recv(recv_pkt_sd, &src_ip, (unsigned char*)buf, sizeof(buf));
|
||||
if(size>0)
|
||||
{
|
||||
send_rec = udp_socket_send(send_pkt_sd,
|
||||
src_ip,
|
||||
htons(port),
|
||||
(char*)buf,size);
|
||||
if(-1==send_rec)
|
||||
{
|
||||
printf("hard_keepalive send pkt error.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hard_keepalive_run(uint32_t udp_port)
|
||||
{
|
||||
if(udp_port<=0) return -1;
|
||||
|
||||
pthread_t thread_desc;
|
||||
pthread_attr_t attr;
|
||||
|
||||
memset(&thread_desc, 0, sizeof(thread_desc));
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
|
||||
if(0 != pthread_attr_init(&(attr)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_attr_setdetachstate(&(attr), PTHREAD_CREATE_DETACHED))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_create(&(thread_desc), &(attr), thread_hard_keepalive, (void*)udp_port))
|
||||
{
|
||||
pthread_attr_destroy(&(attr));
|
||||
return -1;
|
||||
}
|
||||
pthread_attr_destroy(&(attr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
18
src/hard_keepalive.h
Normal file
18
src/hard_keepalive.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _HARD_KEEPALIVE_H
|
||||
#define _HARD_KEEPALIVE_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*return 0:succ -1:fail*/
|
||||
int hard_keepalive_run(uint32_t udp_port);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
156
src/inc/MESA_timer.h
Normal file
156
src/inc/MESA_timer.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/************************************************
|
||||
* MESA timer API
|
||||
* author:tangqi@iie.ac.cn,zhengchao@iie.ac.cn
|
||||
* version: v1.0
|
||||
* last modify:2015.08.18
|
||||
************************************************/
|
||||
|
||||
#ifndef _MESA_TIMER_INCLUDE_
|
||||
#define _MESA_TIMER_INCLUDE_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Timer's handler */
|
||||
typedef struct{
|
||||
}MESA_timer_t;
|
||||
|
||||
typedef struct{
|
||||
}MESA_timer_index_t;
|
||||
|
||||
typedef void (*timeout_cb_t)(void *event);
|
||||
typedef void (*event_free_cb_t)(void *event);
|
||||
|
||||
#define TM_TYPE_QUEUE 0
|
||||
#define TM_TYPE_WHEEL 1
|
||||
|
||||
#define MAX_WHEEL_SIZE 10000
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Create a timer with type of TS_TYPE. Until now we support queue
|
||||
* and time wheel.
|
||||
* Params:
|
||||
* wheel_size: When timer's type is TM_TYPE_QUEUE, wheel_size is unused. It is
|
||||
* the size to initlize time wheel
|
||||
* TS_TYPE: It is a micro defination for timer's type.
|
||||
* TM_TYPE_QUEUE represents double linedlist,
|
||||
* TM_TYPE_WHEEL represents time wheel.
|
||||
* Return:
|
||||
* On success, return a timer, else return NULL
|
||||
*
|
||||
**/
|
||||
MESA_timer_t *MESA_timer_create(long wheel_size, int TM_TYPE);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Add a timeout work to a given timer
|
||||
* Params:
|
||||
* timer: The timer returned by MESA_timer_create function.
|
||||
* current_time: The current time when add the timer element. It MUST >= 0
|
||||
* timeout: The work's timeout time. It MUST >= 0
|
||||
* timeout_cb: It is callback function of a work when timeout.
|
||||
* event: It is the event for user to define.
|
||||
* free_cb: event's free callback function.
|
||||
* index: Address(Index) of the timer_node pointer related to the event is
|
||||
* stored in index.
|
||||
* Return:
|
||||
* On success 0 is returned, else -1 is returned
|
||||
**/
|
||||
int MESA_timer_add(MESA_timer_t *timer,
|
||||
long current_time,
|
||||
long timeout,
|
||||
timeout_cb_t timeout_cb,
|
||||
void* event,
|
||||
event_free_cb_t free_cb,
|
||||
MESA_timer_index_t **index);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Delete a MESA_timer_index_t from timer, and then execute callback function.
|
||||
* Params:
|
||||
* timer: The timer created by MESA_timer_create.
|
||||
* index: MESA_timer_index_t structure returned by MESA_timer_add function.
|
||||
* Now we want to delete it.
|
||||
* Return:
|
||||
* On success, return the event's expire. Otherwise -1 is returned.
|
||||
**/
|
||||
long MESA_timer_del(MESA_timer_t *timer, MESA_timer_index_t *index);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* This function is called by user one or severial times every time_tick.
|
||||
* It will check event's in timer and find the events which are timeout.
|
||||
* Then invoke the callback function registered by related event.
|
||||
* Params:
|
||||
* timer: The same as upper funtion.
|
||||
* current_tick: Current time when call MESA_timer_check function. NOTE
|
||||
* that it is also absolute time, and have the same accuracy
|
||||
* with the timeout in function MESA_timer_add.
|
||||
* max_cb_times: Max times to call callback function.
|
||||
* Return:
|
||||
* Return execute times of callback if success, 0 means no timeout event.
|
||||
* Return -1 when error occurs.
|
||||
**/
|
||||
long MESA_timer_check(MESA_timer_t *timer, long current_time, long max_cb_times);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Destroy the given timer, free the memory and execute callback function.
|
||||
* Params:
|
||||
* timer: The timer we wants to destroy.
|
||||
* Return:
|
||||
* void
|
||||
**/
|
||||
|
||||
void MESA_timer_destroy(MESA_timer_t *timer);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Get the count of events in timer
|
||||
* Params:
|
||||
* timer: Timer returned by MESA_timer_create function.
|
||||
* Return:
|
||||
* Return the count of events in timer.
|
||||
**/
|
||||
long MESA_timer_count(MESA_timer_t *timer);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Get the memory of timer
|
||||
* Params:
|
||||
* timer: Timer returned by MESA_timer_create function.
|
||||
* Return:
|
||||
* Return the memory occupancy of timer.
|
||||
**/
|
||||
|
||||
long MESA_timer_memsize(MESA_timer_t *timer);
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Reset an existing timer element to new current_time and timeout.
|
||||
* Params:
|
||||
* timer: The timer returned by MESA_timer_create function.
|
||||
* index: pointer to a pointer of timer element't index.
|
||||
* current_time: current time.
|
||||
* timeout: relative timeout of timer element.
|
||||
* Return:
|
||||
* On success, 0 is returned, else -1 is returned.
|
||||
**/
|
||||
int MESA_timer_reset(MESA_timer_t *timer, MESA_timer_index_t *index, long current_time, long timeout);
|
||||
void MESA_timer_idx_print(MESA_timer_index_t *index);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_MESA_TIMER_INCLUDE_
|
||||
147
src/inc/MESA_trace.h
Normal file
147
src/inc/MESA_trace.h
Normal file
@@ -0,0 +1,147 @@
|
||||
#ifndef _MESA_TRACE_H_
|
||||
#define _MESA_TRACE_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
#define H_TRACE_VERSION_1_20150204 0
|
||||
|
||||
typedef void* MESA_trace_addr_handle_t;
|
||||
typedef void* MESA_trace_fullstr_handle_t;
|
||||
typedef void* MESA_trace_substr_handle_t;
|
||||
typedef void* MESA_trace_numerical_handle_t;
|
||||
|
||||
struct trace_tuple4_v4
|
||||
{
|
||||
unsigned int saddr;
|
||||
unsigned int daddr;
|
||||
unsigned short source;
|
||||
unsigned short dest;
|
||||
};
|
||||
|
||||
#ifndef IPV6_ADDR_LEN
|
||||
#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
|
||||
#endif
|
||||
|
||||
struct trace_tuple4_v6
|
||||
{
|
||||
unsigned char saddr[IPV6_ADDR_LEN] ;
|
||||
unsigned char daddr[IPV6_ADDR_LEN] ;
|
||||
unsigned short source;
|
||||
unsigned short dest;
|
||||
};
|
||||
|
||||
enum trace_addr_type_t
|
||||
{
|
||||
_TRACE_ADDR_TYPE_INIT = 0,
|
||||
TRACE_ADDR_TYPE_IPV4 = 1,
|
||||
TRACE_ADDR_TYPE_IPV6 = 2,
|
||||
TRACE__ADDR_TYPE_IP_PAIR_V4 = 12,
|
||||
TRACE__ADDR_TYPE_IP_PAIR_V6 = 13,
|
||||
};
|
||||
|
||||
/*stream.h*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char addrtype;
|
||||
unsigned char pkttype;
|
||||
unsigned char addrlen;
|
||||
unsigned char __pad[5];
|
||||
union
|
||||
{
|
||||
struct trace_tuple4_v4 *tuple4_v4;
|
||||
struct trace_tuple4_v6 *tuple4_v6;
|
||||
};
|
||||
}trace_layer_addr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*-------------------------------Part1-------------------------------------------*/
|
||||
/*
|
||||
*Paras: logger: trace runtime_log; filename: configure file
|
||||
*Return: addr_trace_handle_t, NULL means error.
|
||||
*configure file form: addr_type\tsip\tsource\tdip\tdest (separator : '\t', ' ', ';')
|
||||
*such as:
|
||||
*4 192.168.10.147 125 10.10.6.203 80
|
||||
*6 10::25:156::5 20662 10::25:156::45 80
|
||||
*4 0 0 0 0 0 (means all IPV4 tuple4)
|
||||
*6 0 0 0 0 0 (means all IPV6 tuple4)
|
||||
*/
|
||||
MESA_trace_addr_handle_t MESA_trace_create_addr_handle(void* logger, const char *filename);
|
||||
/*
|
||||
*Paras: handle: addr_trace_handle_t paddr:addr
|
||||
*Return: 1 when match success, return 0 when match failed
|
||||
*/
|
||||
int MESA_trace_match_addr(MESA_trace_addr_handle_t handle, trace_layer_addr *paddr);
|
||||
void MESA_trace_destory_addr_handle(MESA_trace_addr_handle_t handle);
|
||||
/*--------------------------------Part2------------------------------------------*/
|
||||
/*
|
||||
*Paras: logger: trace runtime_log; filename: configure file
|
||||
*Return: trace_substr_handle_t
|
||||
*configure file form: string
|
||||
*such as:
|
||||
*192.168.10.123:26662
|
||||
*10:25::68:58
|
||||
*then 192.168.10.123:2545-55.25.65.55:123 will match
|
||||
*/
|
||||
MESA_trace_substr_handle_t MESA_trace_create_substr_handle(void* logger, const char *filename);
|
||||
/*
|
||||
*Paras: handle: trace_substr_handle_t ; str: str_len:
|
||||
*Return: 1 when match success, return 0 when match failed
|
||||
*func: sub match
|
||||
*/
|
||||
int MESA_trace_match_substr(MESA_trace_substr_handle_t handle, const char *str, int str_len);
|
||||
void MESA_trace_destory_substr_handle(MESA_trace_substr_handle_t handle);
|
||||
|
||||
/*-------------------------------Part3-------------------------------------------*/
|
||||
/*
|
||||
*Paras: logger: trace runtime_log; filename: configure file
|
||||
*Return: trace_fullstr_handle_t
|
||||
*configure file form: string
|
||||
*such as:
|
||||
*HTTP
|
||||
*MAIL
|
||||
*then HTTP will match , HTTP_UP will not match
|
||||
*/
|
||||
MESA_trace_fullstr_handle_t MESA_trace_create_fullstr_handle(void* logger, const char *filename);
|
||||
/*
|
||||
*Paras: handle: addr_trace_handle_t ; str: str_len:
|
||||
*Return: 1 when match success, return 0 when match failed
|
||||
*func: complete match
|
||||
*/
|
||||
int MESA_trace_match_fullstr(MESA_trace_fullstr_handle_t handle, const char *str, int str_len);
|
||||
void MESA_trace_destory_fullstr_handle(MESA_trace_fullstr_handle_t handle);
|
||||
|
||||
|
||||
/*-------------------------------Part4-------------------------------------------*/
|
||||
/*
|
||||
*Paras: logger: trace runtime_log; filename: configure file
|
||||
*Return: trace_fullstr_handle_t
|
||||
*configure file form: string
|
||||
*such as:
|
||||
*HTTP
|
||||
*MAIL
|
||||
*then HTTP will match , HTTP_UP will not match
|
||||
*/
|
||||
MESA_trace_numerical_handle_t MESA_trace_create_numerical_handle(void* logger, const char *filename);
|
||||
|
||||
/*
|
||||
*Paras: handle: addr_trace_handle_t ; str: str_len:
|
||||
*Return: 1 when match success, return 0 when match failed
|
||||
*func: complete match
|
||||
*/
|
||||
int MESA_trace_match_numerial(MESA_trace_numerical_handle_t handle, uint64_t value);
|
||||
void MESA_trace_destory_numberial_handle(MESA_trace_numerical_handle_t handle);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
35
src/inc/app_detect.h
Normal file
35
src/inc/app_detect.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __APP_DETECT_H__
|
||||
#define __APP_DETECT_H__
|
||||
|
||||
#define TUPLE4_TYPE_V4 1
|
||||
#define TUPLE4_TYPE_V6 2
|
||||
|
||||
typedef enum __APP_TYPE
|
||||
{
|
||||
APP_TYPE_UNKNOWN=1,
|
||||
APP_TYPE_ANDROID,
|
||||
APP_TYPE_IOS,
|
||||
}APP_TYPE_t;
|
||||
|
||||
typedef struct __appdtc_detail
|
||||
{
|
||||
char *tuple4;
|
||||
char *user_agent;
|
||||
char *url;
|
||||
void *app_data;
|
||||
unsigned int tuple4_len;
|
||||
unsigned short app_type; //APP_TYPE_t
|
||||
unsigned int ua_len;
|
||||
unsigned int url_len;
|
||||
unsigned long long data_len;
|
||||
unsigned long long appid;
|
||||
}appdtc_detail_t;
|
||||
|
||||
typedef void * appdtc_handle_t;
|
||||
|
||||
extern "C" appdtc_handle_t APPDETECT_PLUG_INIT(int thread_num, const char *conf_file_name);
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ: 0-succ
|
||||
extern "C" int APPDTC_PLUG_ENTRY(appdtc_handle_t handle, appdtc_detail_t *detail, unsigned int thread_id);
|
||||
|
||||
#endif
|
||||
|
||||
25
src/inc/appdsender.h
Normal file
25
src/inc/appdsender.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _APPDSENDER_H
|
||||
#define _APPDSENDER_H
|
||||
|
||||
#include "opt.h"
|
||||
#include "MESA_tcp_interface.h"
|
||||
|
||||
typedef void* appdsender_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*gloable init*/
|
||||
int init_appdsender(int iovalue, int thread_num, uint32 local_ip_nr);
|
||||
void release_appdsender();
|
||||
|
||||
appdsender_t creat_appdsender(uint32 sendip, uint16 port, char is_trace, const char* fileinfo,int thread_seq);
|
||||
int appdsender(appdsender_t handle, opt_t opt, int thread_seq);
|
||||
void destory_appdsender(appdsender_t handle, int thread_seq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
76
src/inc/asmis_log.h
Normal file
76
src/inc/asmis_log.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef __ASMIS_LOG_H
|
||||
#define __ASMIS_LOG_H
|
||||
#ifndef __cplusplus
|
||||
#error("This file should be compiled with C++ compiler")
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
//#include <support/thread_safe.h>
|
||||
|
||||
#define ASMIS_KEY 0x01
|
||||
#define ASMIS_ALARM 0x02
|
||||
#define ASMIS_OTHER 0x03
|
||||
|
||||
#define ASMIS_LOGMSG_TIMEOUT 300 //second
|
||||
#define ASMIS_LOGMSG_LENGTH 40000 //bytes
|
||||
|
||||
//系统使用端口信息结构体
|
||||
struct info_port_used {
|
||||
unsigned short nPort;
|
||||
unsigned char nProtocolType;
|
||||
unsigned char nPortType;
|
||||
char sPortDesc[128];
|
||||
};
|
||||
|
||||
//系统实时流量信息结构体
|
||||
struct info_rtd_flow {
|
||||
char sValType[32];
|
||||
char sBDType[32];
|
||||
time_t nRTTS;
|
||||
int nDuration;
|
||||
unsigned long long nValue;
|
||||
};
|
||||
|
||||
//系统策略更新信息结构体
|
||||
struct info_policy_update {
|
||||
char sName[128];
|
||||
char sDesc[256];
|
||||
time_t nUpdateTime;
|
||||
char sVersion[33];
|
||||
int nTotal;
|
||||
int nNew;
|
||||
int nDelete;
|
||||
int nUpdate;
|
||||
int nSize;
|
||||
};
|
||||
|
||||
//NetLog初始化
|
||||
void* asmis_log_Init(const char *pProcName);
|
||||
//登记程序版本信息
|
||||
int asmis_log_AppVer(void* netlog_handle,const char *pVersionTime, const char *pVersionNO, const char *pVersionDesc);
|
||||
//系统运行日志
|
||||
int asmis_log_LogMsg(void* netlog_handle,const char *pMsg, const char *pNo, int nAlarmType);
|
||||
//登记系统使用端口
|
||||
int asmis_log_PortUsed(void* netlog_handle,struct info_port_used *info, int nPort);
|
||||
//登记系统实时流量信息
|
||||
int asmis_log_RtdFlow(void* netlog_handle,time_t nStartTime, int nDuration, struct info_rtd_flow *info, int nFlow);
|
||||
//登记系统开始运行
|
||||
int asmis_log_RunStart(void* netlog_handle,int nContiRun);
|
||||
//登记系统停止信息
|
||||
int asmis_log_RunStop(void* netlog_handle,int nContiRun);
|
||||
//心跳信息
|
||||
int asmis_log_HeartBeat(void* netlog_handle,const char *pMsg);
|
||||
//策略更新信息
|
||||
int asmis_log_Policy(void* netlog_handle,struct info_policy_update *info, int nPolicy);
|
||||
|
||||
#endif
|
||||
161
src/inc/bizman.h
Normal file
161
src/inc/bizman.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*Businessman Data Exchange System
|
||||
*Based on the short story "The fisherman and the businessman"
|
||||
*Author:zhengchao@iie.ac.cn
|
||||
*History:2011-08-24 first build;
|
||||
2011-09-20 v0.01 start test;
|
||||
2011-12-31 v0.02 multi bug fixed;
|
||||
2012-01-16 memset 1MB memory can cause obvious performance reduction;
|
||||
2012-01-19 v0.03 1)support multi cast interface
|
||||
2)support smooth by dest ip and port;
|
||||
2012-03-06 v0.04 1)fix crash recovery bug;
|
||||
2)support chunk mode receive;
|
||||
3)support push send,send immediately after smooth without timeout;
|
||||
2012-03-08 v0.05 1)add choke recv mode,recv will blocked if no data in bizman;
|
||||
2012-03-12 v0.06 1)add magic number as packet header check;
|
||||
2)fix bug,when receiver crash restore leave gabarge in to_ack_timout_queue and
|
||||
ready_index_queue;
|
||||
2012-03-13 v0.07 1)count_last_frag_num_in_packet bug fixed;
|
||||
2)defrozen failed bug caused by no sendtimes reset fixed;
|
||||
3)fix memleaks at destory sender when receiver crush;
|
||||
2012-03-15 v0.07 1)fix copy_recv_data's queue operation before mutex;
|
||||
2)defrozen stream's first slice maybe incomplete is normal,because its previous part
|
||||
have been abandoned;
|
||||
2012-03-19 v0.08 1)add use pag(special network interface)send packets;
|
||||
2012-03-20 v0.09 1)reconstruct bizman.h,hide internal information to outside;
|
||||
2012-03-21 v0.10 1)use define instead of const in bizman.h
|
||||
2)rename functions in hash.cpp,to avoid function name collision in link
|
||||
2012-03-22 v0.11 1)add simple statistic,read reliable layer's stream first packet send and resend count;
|
||||
2012-03-26 v0.12 add reliable receive stream expire,fix stream expire bug in reliabe send;
|
||||
2012-03-29 v0.13 1)fix stream expire bug in reliable receive;
|
||||
2) improve send and resend statistic;
|
||||
2012-04-01 v0.14 1)fix bug when receive reduandent force establish stream packet reduandent, cause
|
||||
app receive duplicate app data.Add force establish stream interval to fix this bug;
|
||||
2)On heavy load,may expire send stream which have in use task, will screwed queue,
|
||||
fixed by check stream's in_use_task_num before expired;
|
||||
2012-04-11 v0.15 1)add sender cached packets limit;
|
||||
2)stat dropped pkts;
|
||||
3)fix bugs, send smooth stream expire time + max resend interval *2 = reliabe recv stream
|
||||
expire time,send smooth stream expire time > reliable send time;
|
||||
2012-04-12 v0.16 1)rebuild stat interface;
|
||||
2)fix bugs of memory corrupt caused by thread conflict when recv,enlarge mutex proctect
|
||||
range;
|
||||
2012-04-14 v0.18 1)fix do_actual_send's sendto return value judgemen;
|
||||
2)fix add_raw_packet function false abandon dup START_SEQ_NUM,also lose first sequence
|
||||
when receiver unordered sequence ;
|
||||
2012-05-11 v0.19 1)fix sender's smooth default interval zero bug;
|
||||
2)fix FORCE_EST_INTERVAL 20min(1000000ms) bug,sho
|
||||
3)fix receiver's ack smooth default interval 10s bug;
|
||||
2012-05-24 v0.20 1)fix smooth block may copy expired father stream bug;
|
||||
2)use mutex_lock instead of try_lock to get smoothed block;
|
||||
3)add thread smooth space limit;
|
||||
2012-06-11 v0.21 1)add choke recv timeout feature;
|
||||
2012-06-18 v0.22 1)businesman_limit.h TIMEOUT_RECV_STREAM_USEC init read array overflow;
|
||||
2)smooth send and reliable send stream expire after send data,a busy receiver may drop lazy
|
||||
sender's packet,move expire operation in front of send;
|
||||
2012-07-24 v1.0 1)check slice_len in is_bizman_packet;
|
||||
2013-03-20 v1.01 1)shorten mutex contension area in recv;
|
||||
2)fix add_raw_packet bugs of filling wrong sequence in ack packet,which caused 250Mbps bottleneck;
|
||||
2013-05-14 v1.02 fix unreliable packet receive dead lock bug in add_raw_packet,caused by v1.01 shorten mutex improvement;
|
||||
2013-06-19 v1.03 1)fix isolate_recv_record dead lock;
|
||||
2)last_send_time type is uint ,cause overflow,change to time_tick_t;
|
||||
2013-07-02 v1.04 v1.01 shorten mutex proved wrong,called deadlock,backward.
|
||||
2013-10-28 v1.05 Not set chunk end after read uncomplete slice.
|
||||
TODO: 1)add select unreachable error;
|
||||
2)add send file interface,save one memory copy time;
|
||||
3)add max memory used limited;
|
||||
|
||||
NOTICE: 1)recv function is NOT thread safe,MUST use your own mutex lock protect the handle;
|
||||
2)send function is thread safe when you send with differenct thread id,but call send function\
|
||||
with the same thread id in different thread is NOT safe;
|
||||
3)unsigned short port is host order,unsigned int ip address is network layer.
|
||||
4)compatible with gcc,link with -lstdc++
|
||||
*/
|
||||
#ifndef _BIZMAN_HEADER_INCLUDE_
|
||||
#define _BIZMAN_HEADER_INCLUDE_
|
||||
|
||||
//initial flag
|
||||
#define BIZMAN_SENDER_ACTIVE 0x01
|
||||
#define BIZMAN_RECEIVER_ACTIVE 0x02
|
||||
|
||||
#define BIZMAN_CHUNK_RECEIVE 0x08
|
||||
#define BIZMAN_CHOKE_RECEIVE 0x10
|
||||
|
||||
|
||||
//set option
|
||||
#define BIZMAN_OPT_SOCKET_INTERFACE_NAME 0x00
|
||||
#define BIZMAN_OPT_PAG_INTERFACE_NAME 0x01
|
||||
|
||||
//set parameter
|
||||
#define BIZMAN_PARAMETER_SEND_SMOOTH_TIME_MSEC 0x01
|
||||
#define BIZMAN_PARAMETER_RESEND_BASE_MSEC 0x02
|
||||
#define BIZMAN_PARAMETER_RESEND_TIMES 0x03 //5 at most
|
||||
#define BIZMAN_PARAMETER_SEND_CACHE_PKTS_LIMIT 0x04
|
||||
#define BIZMAN_PARAMETER_ACK_ACCUMULATE_NUM 0x05
|
||||
#define BIZMAN_PARAMETER_ACK_ACCUMULATE_MSEC 0x06
|
||||
#define BIZMAN_PARAMETER_SEND_WINDOWSIZE 0x07
|
||||
#define BIZMAN_PARAMETER_RECV_WINDOWSIZE 0x08
|
||||
#define BIZMAN_PARAMETER_ACK_SMOOTH_TIME_MSEC 0x09
|
||||
#define BIZMAN_PARAMETER_FROZEN_STREAM_MSEC 0x0a
|
||||
#define BIZMAN_PARAMETER_SMOOTH_CACHE_PKTS_LIMIT 0x0b
|
||||
|
||||
#define BIZMAN_PARAMETER_CHUNK_RECEIVE 0x10
|
||||
#define BIZMAN_PARAMETER_CHOKE_RECEIVE 0x11
|
||||
#define BIZMAN_PARAMETER_CHOKE_RECV_TIMEOUT_MSEC 0x12
|
||||
|
||||
//send flag
|
||||
#define BIZMAN_RELIABLE_SEND 0x01
|
||||
#define BIZMAN_UNRELIABLE_SEND 0x00
|
||||
#define BIZMAN_LAST_PKT 0x02
|
||||
#define BIZMAN_PUSH_SEND 0x04
|
||||
#define BIZMAN_SMOOTH_DEST 0x08
|
||||
|
||||
|
||||
//recv flag
|
||||
#define BIZMAN_READ_CRAM 0x00
|
||||
#define BIZMAN_READ_STREAM 0x01
|
||||
#define BIZMAN_READ_CHUNK 0x02
|
||||
|
||||
//stat
|
||||
#define BIZMAN_STAT_FIRST_SEND_PKTS 0x01
|
||||
#define BIZMAN_STAT_FIRST_RESEND_PKTS 0x02
|
||||
#define BIZMAN_STAT_LAST_RESEND 0x03
|
||||
#define BIZMAN_STAT_MEM_DROPPED 0x04
|
||||
#define BIZMAN_STAT_FROZEN_DROPPED 0x05
|
||||
#define BIZMAN_STAT_ACK_PKT_NUM 0x06
|
||||
#define BIZMAN_STAT_FIRST_SEND_STREAM 0x07
|
||||
#define BIZMAN_STAT_FIRST_RESEND_STREAM 0x08
|
||||
#define BIZMAN_STAT_ACTIVE_STREAM 0x09
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
/*
|
||||
*return an unintialized handle when success;
|
||||
*return NULL when failed.
|
||||
*/
|
||||
void *bizman_get_handle(void);
|
||||
void bizman_destroy_handle(void * raw_handle);
|
||||
/*
|
||||
BIZMAN_SENDER_ACTIVE:0x01;BIZMAN_RECEIVER_ACTIVE:0x02;BIZMAN_PAG_USE:0x04;
|
||||
*/
|
||||
int bizman_set_handle(void* raw_handle,unsigned short flags);
|
||||
int bizman_set_handle_option(void* raw_handle,int option_type, const char* option_value);
|
||||
int bizman_set_handle_parameter(void* raw_handle,int type, unsigned int value);
|
||||
//only used on sender
|
||||
int bizman_set_pkts_cached_limit(void* raw_handle,unsigned long long cached_pkts_limit);
|
||||
|
||||
//unsigned short port is host order,unsigned int ip address is network layer.
|
||||
int bizman_listen(void* raw_handle,unsigned short port);
|
||||
int bizman_init_handle(void* raw_handle);
|
||||
|
||||
int bizman_recv(void* raw_handle,char* buff,int buf_len,unsigned int *src_ip,unsigned short *src_port,unsigned int *stream_id,unsigned int* is_complete);
|
||||
int bizman_send(void* raw_handle,unsigned int thread_id,unsigned int dest_ip,unsigned short dest_port,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags);
|
||||
int bizman_multi_send(void* raw_handle,unsigned int thread_id,const unsigned int *dest_ip,const unsigned short *dest_port,unsigned int dest_num,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags);
|
||||
unsigned long long bizman_stat(void* raw_handle,int type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
26
src/inc/dynamic_array.h
Normal file
26
src/inc/dynamic_array.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _DYNAMIC_ARRAY_H_
|
||||
#define _DYNAMIC_ARRAY_H_
|
||||
|
||||
#define DYNAMIC_ARRAY_DEBUG (1)
|
||||
|
||||
typedef void * maskey_dynamic_array_handle;
|
||||
|
||||
typedef int (* maskey_dynamic_array_init_cb)(void *struct_data);
|
||||
typedef int (* maskey_dynamic_array_iterate_cb)(int index, void *struct_data, void *user_arg);
|
||||
typedef int (* maskey_dynamic_array_safe_copy_cb)(int index, void *new_data, void *old_data);
|
||||
|
||||
maskey_dynamic_array_handle maskey_dynamic_array_init(int struct_len, int array_init_num, int array_max_num);
|
||||
maskey_dynamic_array_handle maskey_dynamic_array_init_with_cb(int struct_len, int array_init_num,
|
||||
int array_max_num, maskey_dynamic_array_init_cb init_cb);
|
||||
void maskey_dynamic_array_destroy(maskey_dynamic_array_handle dah, maskey_dynamic_array_iterate_cb cb, void *);
|
||||
int maskey_dynamic_array_append(maskey_dynamic_array_handle dah, void *struct_data, int struct_len);
|
||||
int maskey_dynamic_array_append_distinct(maskey_dynamic_array_handle dah, void *struct_data, int struct_len);
|
||||
void *maskey_dynamic_array_fetch(maskey_dynamic_array_handle dah, int index);
|
||||
int maskey_dynamic_array_get_num(maskey_dynamic_array_handle dah);
|
||||
void *maskey_dynamic_array_get_data(maskey_dynamic_array_handle dah);
|
||||
void *maskey_dynamic_array_get_last_item(maskey_dynamic_array_handle dah);
|
||||
int maskey_dynamic_array_iterate(maskey_dynamic_array_handle dah, maskey_dynamic_array_iterate_cb cb, void *user_arg);
|
||||
maskey_dynamic_array_handle maskey_dynamic_array_quick_copy(maskey_dynamic_array_handle old_dah);
|
||||
|
||||
#endif
|
||||
|
||||
66
src/inc/field_stat2.h
Normal file
66
src/inc/field_stat2.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef H_SCREEN_STAT_H_INCLUDE
|
||||
#define H_SCREEN_STAT_H_INCLUDE
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error("This file should be compiled with C++ compiler")
|
||||
#endif
|
||||
|
||||
enum field_dsp_style_t
|
||||
{
|
||||
FS_STYLE_FIELD=0,
|
||||
FS_STYLE_COLUMN,
|
||||
FS_STYLE_LINE,
|
||||
FS_STYLE_STATUS
|
||||
};
|
||||
enum field_calc_algo
|
||||
{
|
||||
FS_CALC_CURRENT=0,
|
||||
FS_CALC_SPEED
|
||||
};
|
||||
enum field_op
|
||||
{
|
||||
FS_OP_ADD=1,
|
||||
FS_OP_SET
|
||||
};
|
||||
|
||||
|
||||
typedef void* screen_stat_handle_t;
|
||||
|
||||
enum FS_option
|
||||
{
|
||||
OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout.
|
||||
PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE.
|
||||
STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds.
|
||||
PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1.
|
||||
CREATE_THREAD, //VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function,
|
||||
//and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0.
|
||||
ID_INVISBLE, //value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one.
|
||||
FLUSH_BY_DATE, //value is 1(ture) or 0(false),SIZE=4,DEFAULT: Do not flush by date.
|
||||
APP_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT is "?".
|
||||
STATS_SERVER_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT.
|
||||
STATS_SERVER_PORT, //VALUE is a unsigned short, host order, SIZE= sizeof(unsigned short). No DEFAULT.
|
||||
};
|
||||
|
||||
//Always success.
|
||||
screen_stat_handle_t FS_create_handle(void);
|
||||
|
||||
int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size);
|
||||
void FS_start(screen_stat_handle_t handle);
|
||||
void FS_stop(screen_stat_handle_t* handle);
|
||||
|
||||
//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed.
|
||||
//should NOT include "|:\n\r.\t<>[]#!@"or space in the parameter name.
|
||||
int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
|
||||
|
||||
//numerator_id and denominator_id must be column/field/status style.
|
||||
//scaling: negative value: zoom in; positive value: zoom out;
|
||||
int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
|
||||
|
||||
//id: when id's type is FIELD , column_id is ignore.
|
||||
int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value);
|
||||
|
||||
void FS_passive_output(screen_stat_handle_t handle);
|
||||
|
||||
#endif
|
||||
|
||||
187
src/inc/hircluster.h
Normal file
187
src/inc/hircluster.h
Normal file
@@ -0,0 +1,187 @@
|
||||
#ifndef __HIRCLUSTER_H
|
||||
#define __HIRCLUSTER_H
|
||||
|
||||
#include "hiredis.h"
|
||||
#include "async.h"
|
||||
#include "command.h"
|
||||
#define HIREDIS_VIP_MAJOR 0
|
||||
#define HIREDIS_VIP_MINOR 2
|
||||
#define HIREDIS_VIP_PATCH 2
|
||||
|
||||
#define REDIS_CLUSTER_SLOTS 16384
|
||||
|
||||
#define REDIS_ROLE_NULL 0
|
||||
#define REDIS_ROLE_MASTER 1
|
||||
#define REDIS_ROLE_SLAVE 2
|
||||
|
||||
|
||||
#define HIRCLUSTER_FLAG_NULL 0x0
|
||||
/* The flag to decide whether add slave node in
|
||||
* redisClusterContext->nodes. This is set in the
|
||||
* least significant bit of the flags field in
|
||||
* redisClusterContext. (1000000000000) */
|
||||
#define HIRCLUSTER_FLAG_ADD_SLAVE 0x1000
|
||||
/* The flag to decide whether add open slot
|
||||
* for master node. (10000000000000) */
|
||||
#define HIRCLUSTER_FLAG_ADD_OPENSLOT 0x2000
|
||||
/* The flag to decide whether add open slot
|
||||
* for master node. (100000000000000) */
|
||||
#define HIRCLUSTER_FLAG_ROUTE_USE_SLOTS 0x4000
|
||||
|
||||
/*
|
||||
The following flags are used for deciding which part of IP will
|
||||
be used when the salve for reading is enabled
|
||||
*/
|
||||
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_ONE 0x100
|
||||
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_TWO 0x200
|
||||
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_THREE 0x400
|
||||
#define HIRCLUSTER_FLAG_UNIQIP_FRAG_FOUR 0x800
|
||||
|
||||
struct dict;
|
||||
struct hilist;
|
||||
|
||||
typedef struct cluster_node
|
||||
{
|
||||
sds name;
|
||||
sds addr;
|
||||
sds host;
|
||||
int port;
|
||||
uint8_t role;
|
||||
uint8_t myself; /* myself ? */
|
||||
redisContext *con;
|
||||
redisAsyncContext *acon;
|
||||
struct hilist *slots;
|
||||
struct hilist *slaves;
|
||||
int failure_count;
|
||||
void *data; /* Not used by hiredis */
|
||||
struct hiarray *migrating; /* copen_slot[] */
|
||||
struct hiarray *importing; /* copen_slot[] */
|
||||
}cluster_node;
|
||||
|
||||
typedef struct cluster_slot
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
cluster_node *node; /* master that this slot region belong to */
|
||||
}cluster_slot;
|
||||
|
||||
typedef struct copen_slot
|
||||
{
|
||||
uint32_t slot_num; /* slot number */
|
||||
int migrate; /* migrating or importing? */
|
||||
sds remote_name; /* name for the node that this slot migrating to/importing from */
|
||||
cluster_node *node; /* master that this slot belong to */
|
||||
}copen_slot;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Context for a connection to Redis cluster */
|
||||
typedef struct redisClusterContext {
|
||||
int err; /* Error flags, 0 when there is no error */
|
||||
char errstr[128]; /* String representation of error when applicable */
|
||||
sds ip;
|
||||
sds *uni_ipfrag;
|
||||
int ipfrag_count;
|
||||
int port;
|
||||
|
||||
int flags;
|
||||
|
||||
enum redisConnectionType connection_type;
|
||||
struct timeval *timeout;
|
||||
|
||||
struct hiarray *slots;
|
||||
|
||||
struct dict *nodes;
|
||||
cluster_node *table[REDIS_CLUSTER_SLOTS];
|
||||
|
||||
uint64_t route_version;
|
||||
|
||||
int max_redirect_count;
|
||||
int retry_count;
|
||||
|
||||
struct hilist *requests;
|
||||
|
||||
int need_update_route;
|
||||
int64_t update_route_time;
|
||||
} redisClusterContext;
|
||||
|
||||
redisClusterContext *redisClusterConnect(const char *addrs, int flags);
|
||||
redisClusterContext *redisClusterConnectWithTimeout(const char *addrs,
|
||||
const struct timeval tv, int flags);
|
||||
redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags);
|
||||
|
||||
void redisClusterFree(redisClusterContext *cc);
|
||||
|
||||
void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
|
||||
|
||||
void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len);
|
||||
void *redisClustervCommand(redisClusterContext *cc, const char *format, va_list ap);
|
||||
void *redisClusterCommand(redisClusterContext *cc, const char *format, ...);
|
||||
void *redisClusterCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
|
||||
|
||||
redisContext *ctx_get_by_node(redisClusterContext *cc, struct cluster_node *node, const struct timeval *timeout, int flags);
|
||||
|
||||
int redisClusterAppendFormattedCommand(redisClusterContext *cc, char *cmd, int len);
|
||||
int redisClustervAppendCommand(redisClusterContext *cc, const char *format, va_list ap);
|
||||
int redisClusterAppendCommand(redisClusterContext *cc, const char *format, ...);
|
||||
int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
|
||||
int redisClusterGetReply(redisClusterContext *cc, void **reply);
|
||||
void redisCLusterReset(redisClusterContext *cc);
|
||||
|
||||
int cluster_update_route(redisClusterContext *cc);
|
||||
int test_cluster_update_route(redisClusterContext *cc);
|
||||
struct dict *parse_cluster_nodes(redisClusterContext *cc, char *str, int str_len, int flags);
|
||||
struct dict *parse_cluster_slots(redisClusterContext *cc, redisReply *reply, int flags);
|
||||
|
||||
|
||||
/*############redis cluster async############*/
|
||||
|
||||
struct redisClusterAsyncContext;
|
||||
|
||||
typedef int (adapterAttachFn)(redisAsyncContext*, void*);
|
||||
|
||||
typedef void (redisClusterCallbackFn)(struct redisClusterAsyncContext*, void*, void*);
|
||||
|
||||
/* Context for an async connection to Redis */
|
||||
typedef struct redisClusterAsyncContext {
|
||||
|
||||
redisClusterContext *cc;
|
||||
|
||||
/* Setup error flags so they can be used directly. */
|
||||
int err;
|
||||
char errstr[128]; /* String representation of error when applicable */
|
||||
|
||||
/* Not used by hiredis */
|
||||
void *data;
|
||||
|
||||
void *adapter;
|
||||
adapterAttachFn *attach_fn;
|
||||
|
||||
/* Called when either the connection is terminated due to an error or per
|
||||
* user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
|
||||
redisDisconnectCallback *onDisconnect;
|
||||
|
||||
/* Called when the first write event was received. */
|
||||
redisConnectCallback *onConnect;
|
||||
|
||||
} redisClusterAsyncContext;
|
||||
|
||||
redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags);
|
||||
int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn);
|
||||
int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn);
|
||||
int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len);
|
||||
int redisClustervAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, va_list ap);
|
||||
int redisClusterAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, ...);
|
||||
int redisClusterAsyncCommandArgv(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
|
||||
void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc);
|
||||
void redisClusterAsyncFree(redisClusterAsyncContext *acc);
|
||||
|
||||
redisAsyncContext *actx_get_by_node(redisClusterAsyncContext *acc, cluster_node *node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
221
src/inc/hiredis.h
Normal file
221
src/inc/hiredis.h
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||
* Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
|
||||
* Jan-Erik Rediger <janerik at fnordig dot com>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HIREDIS_H
|
||||
#define __HIREDIS_H
|
||||
#include "read.h"
|
||||
#include <stdarg.h> /* for va_list */
|
||||
#include <sys/time.h> /* for struct timeval */
|
||||
#include <stdint.h> /* uintXX_t, etc */
|
||||
#include "sds.h" /* for sds */
|
||||
|
||||
#define HIREDIS_MAJOR 0
|
||||
#define HIREDIS_MINOR 13
|
||||
#define HIREDIS_PATCH 1
|
||||
|
||||
/* Connection type can be blocking or non-blocking and is set in the
|
||||
* least significant bit of the flags field in redisContext. */
|
||||
#define REDIS_BLOCK 0x1
|
||||
|
||||
/* Connection may be disconnected before being free'd. The second bit
|
||||
* in the flags field is set when the context is connected. */
|
||||
#define REDIS_CONNECTED 0x2
|
||||
|
||||
/* The async API might try to disconnect cleanly and flush the output
|
||||
* buffer and read all subsequent replies before disconnecting.
|
||||
* This flag means no new commands can come in and the connection
|
||||
* should be terminated once all replies have been read. */
|
||||
#define REDIS_DISCONNECTING 0x4
|
||||
|
||||
/* Flag specific to the async API which means that the context should be clean
|
||||
* up as soon as possible. */
|
||||
#define REDIS_FREEING 0x8
|
||||
|
||||
/* Flag that is set when an async callback is executed. */
|
||||
#define REDIS_IN_CALLBACK 0x10
|
||||
|
||||
/* Flag that is set when the async context has one or more subscriptions. */
|
||||
#define REDIS_SUBSCRIBED 0x20
|
||||
|
||||
/* Flag that is set when monitor mode is active */
|
||||
#define REDIS_MONITORING 0x40
|
||||
|
||||
/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
|
||||
#define REDIS_REUSEADDR 0x80
|
||||
|
||||
#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
|
||||
|
||||
/* number of times we retry to connect in the case of EADDRNOTAVAIL and
|
||||
* SO_REUSEADDR is being used. */
|
||||
#define REDIS_CONNECT_RETRIES 10
|
||||
|
||||
/* strerror_r has two completely different prototypes and behaviors
|
||||
* depending on system issues, so we need to operate on the error buffer
|
||||
* differently depending on which strerror_r we're using. */
|
||||
#ifndef _GNU_SOURCE
|
||||
/* "regular" POSIX strerror_r that does the right thing. */
|
||||
#define __redis_strerror_r(errno, buf, len) \
|
||||
do { \
|
||||
strerror_r((errno), (buf), (len)); \
|
||||
} while (0)
|
||||
#else
|
||||
/* "bad" GNU strerror_r we need to clean up after. */
|
||||
#define __redis_strerror_r(errno, buf, len) \
|
||||
do { \
|
||||
char *err_str = strerror_r((errno), (buf), (len)); \
|
||||
/* If return value _isn't_ the start of the buffer we passed in, \
|
||||
* then GNU strerror_r returned an internal static buffer and we \
|
||||
* need to copy the result into our private buffer. */ \
|
||||
if (err_str != (buf)) { \
|
||||
buf[(len)] = '\0'; \
|
||||
strncat((buf), err_str, ((len) - 1)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This is the reply object returned by redisCommand() */
|
||||
typedef struct redisReply {
|
||||
int type; /* REDIS_REPLY_* */
|
||||
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
|
||||
int len; /* Length of string */
|
||||
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
|
||||
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
|
||||
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
|
||||
} redisReply;
|
||||
|
||||
redisReader *redisReaderCreate(void);
|
||||
|
||||
/* Function to free the reply objects hiredis returns by default. */
|
||||
void freeReplyObject(void *reply);
|
||||
|
||||
/* Functions to format a command according to the protocol. */
|
||||
int redisvFormatCommand(char **target, const char *format, va_list ap);
|
||||
int redisFormatCommand(char **target, const char *format, ...);
|
||||
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
|
||||
int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
|
||||
void redisFreeCommand(char *cmd);
|
||||
void redisFreeSdsCommand(sds cmd);
|
||||
|
||||
enum redisConnectionType {
|
||||
REDIS_CONN_TCP,
|
||||
REDIS_CONN_UNIX,
|
||||
};
|
||||
|
||||
/* Context for a connection to Redis */
|
||||
typedef struct redisContext {
|
||||
int err; /* Error flags, 0 when there is no error */
|
||||
char errstr[128]; /* String representation of error when applicable */
|
||||
int fd;
|
||||
int flags;
|
||||
char *obuf; /* Write buffer */
|
||||
redisReader *reader; /* Protocol reader */
|
||||
|
||||
enum redisConnectionType connection_type;
|
||||
struct timeval *timeout;
|
||||
|
||||
struct {
|
||||
char *host;
|
||||
char *source_addr;
|
||||
int port;
|
||||
} tcp;
|
||||
|
||||
struct {
|
||||
char *path;
|
||||
} unix_sock;
|
||||
} redisContext;
|
||||
|
||||
redisContext *redisConnect(const char *ip, int port);
|
||||
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
|
||||
redisContext *redisConnectNonBlock(const char *ip, int port);
|
||||
redisContext *redisConnectBindNonBlock(const char *ip, int port,
|
||||
const char *source_addr);
|
||||
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
|
||||
const char *source_addr);
|
||||
redisContext *redisConnectUnix(const char *path);
|
||||
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
|
||||
redisContext *redisConnectUnixNonBlock(const char *path);
|
||||
redisContext *redisConnectFd(int fd);
|
||||
|
||||
/**
|
||||
* Reconnect the given context using the saved information.
|
||||
*
|
||||
* This re-uses the exact same connect options as in the initial connection.
|
||||
* host, ip (or path), timeout and bind address are reused,
|
||||
* flags are used unmodified from the existing context.
|
||||
*
|
||||
* Returns REDIS_OK on successfull connect or REDIS_ERR otherwise.
|
||||
*/
|
||||
int redisReconnect(redisContext *c);
|
||||
|
||||
int redisSetTimeout(redisContext *c, const struct timeval tv);
|
||||
int redisEnableKeepAlive(redisContext *c);
|
||||
void redisFree(redisContext *c);
|
||||
int redisFreeKeepFd(redisContext *c);
|
||||
int redisBufferRead(redisContext *c);
|
||||
int redisBufferWrite(redisContext *c, int *done);
|
||||
|
||||
/* In a blocking context, this function first checks if there are unconsumed
|
||||
* replies to return and returns one if so. Otherwise, it flushes the output
|
||||
* buffer to the socket and reads until it has a reply. In a non-blocking
|
||||
* context, it will return unconsumed replies until there are no more. */
|
||||
int redisGetReply(redisContext *c, void **reply);
|
||||
int redisGetReplyFromReader(redisContext *c, void **reply);
|
||||
|
||||
/* Write a formatted command to the output buffer. Use these functions in blocking mode
|
||||
* to get a pipeline of commands. */
|
||||
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
|
||||
|
||||
/* Write a command to the output buffer. Use these functions in blocking mode
|
||||
* to get a pipeline of commands. */
|
||||
int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
|
||||
int redisAppendCommand(redisContext *c, const char *format, ...);
|
||||
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
|
||||
|
||||
/* Issue a command to Redis. In a blocking context, it is identical to calling
|
||||
* redisAppendCommand, followed by redisGetReply. The function will return
|
||||
* NULL if there was an error in performing the request, otherwise it will
|
||||
* return the reply. In a non-blocking context, it is identical to calling
|
||||
* only redisAppendCommand and will always return NULL. */
|
||||
void *redisvCommand(redisContext *c, const char *format, va_list ap);
|
||||
void *redisCommand(redisContext *c, const char *format, ...);
|
||||
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
313
src/inc/interval_index.h
Normal file
313
src/inc/interval_index.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/************************************************************************
|
||||
* InterVal Index interface
|
||||
* NOTE that:
|
||||
* (1) There are no overlapping intervals in InterVal Index;
|
||||
* (2) Each interval is closed;
|
||||
* (3) The interval supports rollback.
|
||||
*
|
||||
* author: zhengchao@iie.ac.cn tangqi@iie.ac.cn
|
||||
* last modify time: 2015-12-04
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _INTERVAL_INDEX_H_
|
||||
#define _INTERVAL_INDEX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
#define SIZE_8
|
||||
|
||||
#ifdef SIZE_8
|
||||
typedef unsigned long OFFSET_TYPE;
|
||||
typedef signed long S_OFFSET_TYPE;
|
||||
#else
|
||||
typedef unsigned int OFFSET_TYPE;
|
||||
typedef signed int S_OFFSET_TYPE;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct{
|
||||
}IVI_t;
|
||||
|
||||
|
||||
/**
|
||||
* structure of segment
|
||||
**/
|
||||
typedef struct __IVI_seg_t{
|
||||
OFFSET_TYPE left;
|
||||
OFFSET_TYPE right;
|
||||
void * data;
|
||||
}IVI_seg_t;
|
||||
|
||||
|
||||
typedef void IVI_callback_t(IVI_seg_t * seg, void * usr_para);
|
||||
|
||||
/**
|
||||
* Deal with rollback
|
||||
* Refering to the approach of Linux's kernel to solute tcp seq rollback
|
||||
**/
|
||||
static inline int before(OFFSET_TYPE off1, OFFSET_TYPE off2)
|
||||
{
|
||||
return (S_OFFSET_TYPE)(off1 - off2) < 0;
|
||||
}
|
||||
#define after(off2, off1) before(off1, off2)
|
||||
|
||||
static inline int continuous(OFFSET_TYPE prev, OFFSET_TYPE next)
|
||||
{
|
||||
return ((next - prev) == 1);
|
||||
}
|
||||
|
||||
|
||||
IVI_seg_t * IVI_first_seg(IVI_t * handler);
|
||||
IVI_seg_t * IVI_last_seg(IVI_t * handler);
|
||||
IVI_seg_t * IVI_prev_seg(IVI_seg_t * seg);
|
||||
IVI_seg_t * IVI_next_seg(IVI_seg_t * seg);
|
||||
IVI_seg_t * IVI_prev_continuous_seg(IVI_seg_t * seg);
|
||||
IVI_seg_t * IVI_next_continuous_seg(IVI_seg_t * seg);
|
||||
|
||||
|
||||
/**
|
||||
* Relation of two segments
|
||||
**/
|
||||
typedef enum __Relation_t{
|
||||
LEFT_NO_OVERLAP = 1, // |___A___|
|
||||
// |___B___|
|
||||
|
||||
LEFT_OVERLAP, // |___A___|
|
||||
// |___B___|
|
||||
|
||||
CONTAINED, // |___A___|
|
||||
// |_____B_____|
|
||||
|
||||
CONTAIN, // |_____A_____|
|
||||
// |___B___|
|
||||
|
||||
RIGHT_OVERLAP, // |___A___|
|
||||
// |___B___|
|
||||
|
||||
RIGHT_NO_OVERLAP, // |___A___|
|
||||
// |___B___|
|
||||
|
||||
ERROR
|
||||
}Relation_t;
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_relative_position
|
||||
* Description:
|
||||
* Get relative position of given two interval segments
|
||||
* Params:
|
||||
* seg1: Subject of relation
|
||||
* seg2: Object of relation
|
||||
* Relation:
|
||||
* On success, return the relation of two segments with enum;
|
||||
* Else, return ERROR in enum;
|
||||
**/
|
||||
Relation_t IVI_relative_position(IVI_seg_t * seg1, IVI_seg_t * seg2);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_create
|
||||
* Description:
|
||||
* Create an InterVal Index
|
||||
* Params:
|
||||
* void
|
||||
* Return:
|
||||
* Return a handler of this InterVal Index
|
||||
**/
|
||||
IVI_t * IVI_create(void);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_destroy
|
||||
* Description:
|
||||
* Destroy a given InterVal Index's handler
|
||||
* Params:
|
||||
* handler: The InterVal Index you want to destroy
|
||||
* cb: Callback function for user to free data in segement
|
||||
* usr_para: User parameter
|
||||
* Return:
|
||||
* void
|
||||
**/
|
||||
void IVI_destroy(IVI_t * handler, IVI_callback_t cb, void * usr_para);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_seg_malloc
|
||||
* Description:
|
||||
* Malloc a segment with given parameters
|
||||
* Params:
|
||||
* left: Left point of segment
|
||||
* right: Right point of segment
|
||||
* data: User data
|
||||
* Return:
|
||||
* Return a pointer of segment structure.
|
||||
**/
|
||||
IVI_seg_t * IVI_seg_malloc(OFFSET_TYPE left, OFFSET_TYPE right, void * data);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_seg_free
|
||||
* Description:
|
||||
* Free the memory of given segment
|
||||
* Params:
|
||||
* seg: The segment that you want to free
|
||||
* cb: Callback function for user to free *data in seg
|
||||
* usr_para: User parameter for cb
|
||||
* Return:
|
||||
* void
|
||||
**/
|
||||
void IVI_seg_free(IVI_seg_t * seg, IVI_callback_t cb, void * usr_para);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_insert
|
||||
* Description:
|
||||
* Insert a segment to an InterVal Index handler,and the segment
|
||||
* MUST not be overlapped with others in handler.
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create
|
||||
* seg: A segment that user wants to add. It MUST be created
|
||||
* by IVI_seg_malloc.
|
||||
* Return:
|
||||
* On success, 0 is returned;
|
||||
* Else when overlapp occures or error occures, -1 is returned.
|
||||
**/
|
||||
int IVI_insert(IVI_t * handler, IVI_seg_t * seg);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_remove
|
||||
* Description:
|
||||
* Remove a given segment from given InterVal Index handler.
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create
|
||||
* seg: A segment that user wants to delete. It MUST be created
|
||||
* by IVI_seg_malloc.
|
||||
* Return:
|
||||
* On success, 0 is returned;
|
||||
* Else when overlapp occures, -1 is returned.
|
||||
**/
|
||||
int IVI_remove(IVI_t * handler, IVI_seg_t * seg);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_query
|
||||
* Description:
|
||||
* Query from given InterVal Index and get the number of segments
|
||||
* which are overlapped with given interval, and store those segments
|
||||
* in the last parameter.
|
||||
* Params:
|
||||
* handler: The handler of interval index created by IVI_create
|
||||
* left: Left point of given interval
|
||||
* right: Right point of given interval
|
||||
* segs: An address of a segment pointer array to store those segments which
|
||||
* are overlapped with given interval. NOTE that user should not malloc
|
||||
* the array, and segs need to be freed by user. The element of *segs
|
||||
* MUST not be freed by user.
|
||||
* Return:
|
||||
* Return the number of segments which are overlapped with given interval
|
||||
**/
|
||||
int IVI_query(IVI_t * handler, OFFSET_TYPE left, OFFSET_TYPE right, IVI_seg_t *** segs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_query_continuous
|
||||
* Description:
|
||||
* Query from interval index handler and get the number of continous segments
|
||||
* which are overlapped with given interval.
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create.
|
||||
* left: Left point of given interval
|
||||
* right: Right point of given interval
|
||||
* segs: An address of a segment pointer array to store those segments which
|
||||
* are overlapped with given interval. NOTE that user should not malloc
|
||||
* the array, and segs need to be freed by user. The element of *segs
|
||||
* MUST not be freed by user.
|
||||
* Return:
|
||||
* Return the number of continous segments which are overlapped with given interval
|
||||
**/
|
||||
int IVI_query_continuous(IVI_t * handler, OFFSET_TYPE left, OFFSET_TYPE right, IVI_seg_t *** segs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_seg_cnt
|
||||
* Description:
|
||||
* Get the count of segments in given interval index handler
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create.
|
||||
* Return:
|
||||
* Return the count of segments in given interval index handler
|
||||
**/
|
||||
int IVI_seg_cnt(IVI_t * handler);
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_seg_len
|
||||
* Description:
|
||||
* Get the length of whole segments in given interval index handler
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create.
|
||||
* Return:
|
||||
* Return the length of whole segments in given interval index handler
|
||||
**/
|
||||
OFFSET_TYPE IVI_seg_length(IVI_t * handler);
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_mem_occupy
|
||||
* Description:
|
||||
* Get the memory occupy of given interval index handler
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create.
|
||||
* Return:
|
||||
* Return the memory occupy of given interval index handler
|
||||
**/
|
||||
unsigned long long IVI_mem_occupy(IVI_t * handler);
|
||||
|
||||
|
||||
/**
|
||||
* Name:
|
||||
* IVI_traverse
|
||||
* Description:
|
||||
* Traverse given InterVal Index and execute given callback function
|
||||
* one time for each seg in InterVal Index.
|
||||
* Params:
|
||||
* handler: The handler of InterVal Index created by IVI_create.
|
||||
* IVI_callback_t: Callback function for user to define.
|
||||
* usr_para: Parameter user want to pass to callback function.
|
||||
* Return:
|
||||
* void
|
||||
**/
|
||||
void IVI_traverse(IVI_t * handler, IVI_callback_t cb, void * usr_para);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INTERVAL_INDEX_H_ */
|
||||
85
src/inc/mesa_fuzzy.h
Normal file
85
src/inc/mesa_fuzzy.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef _MESA_FUZZY_
|
||||
#define _MESA_FUZZY_
|
||||
|
||||
/*
|
||||
* Copyright (C) MESA 2015
|
||||
*
|
||||
* These functions allow a programmer to compute the fuzzy hashes
|
||||
* (also called the context-triggered piecewise hashes) of
|
||||
* buffer[s] of text.
|
||||
*
|
||||
* See also:
|
||||
* ssdeep, and
|
||||
* Identifying almost identical files using context triggered piecewise hashing
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TOTAL_LENGTH 0
|
||||
#define EFFECTIVE_LENGTH 1
|
||||
#define HASH_LENGTH 2
|
||||
|
||||
// typedef fuzzy_handle_t void*;
|
||||
typedef struct
|
||||
{
|
||||
}fuzzy_handle_t;
|
||||
|
||||
/**
|
||||
* create a fuzzy hash handle and return it.
|
||||
* @return [handle]
|
||||
*/
|
||||
fuzzy_handle_t * fuzzy_create_handle(unsigned long long origin_len);
|
||||
|
||||
/**
|
||||
* destroy context by a fuzzy hash handle.
|
||||
* @param handle [handle]
|
||||
*/
|
||||
void fuzzy_destroy_handle(fuzzy_handle_t * handle);
|
||||
|
||||
/**
|
||||
* Feed the function your data.
|
||||
* Call this function several times, if you have several parts of data to feed.
|
||||
* @param handle [handle]
|
||||
* @param data [data that you want to fuzzy_hash]
|
||||
* @param size [data size]
|
||||
* @param offset [offset]
|
||||
* @return [return effective data length in current feed]
|
||||
*/
|
||||
unsigned int fuzzy_feed(fuzzy_handle_t * handle, const char* data, unsigned int size, unsigned long long offset);
|
||||
|
||||
/**
|
||||
* Obtain the fuzzy hash values.
|
||||
* @param handle [handle]
|
||||
* @param result [fuzzy hash result]
|
||||
* Fuzzy hash result with offsets(in the square brackets, with colon splitted).
|
||||
* eg. abc[1:100]def[200:300]
|
||||
* @param size [@result size]
|
||||
* @return [return zero on success, non-zero on error]
|
||||
*/
|
||||
int fuzzy_digest(fuzzy_handle_t * handle, char* result, unsigned int size);
|
||||
|
||||
/**
|
||||
* Obtain certain length of fuzzy hash status.
|
||||
* @param handle [handle]
|
||||
* @param type [length type]
|
||||
* TOTAL_LENGTH:Total length of data you have fed.
|
||||
* Overlapped data will NOT count for 2 times.
|
||||
* EFFECTIVE_LENGTH:Length of data that involved in the calculation of hash.
|
||||
* HASH_LENGTH:Hash result length.
|
||||
* @return [length value]
|
||||
*/
|
||||
unsigned long long fuzzy_status(fuzzy_handle_t * handle, int type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
28
src/inc/my_socket.h
Normal file
28
src/inc/my_socket.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _MY_SOCKET_H_
|
||||
#define _MY_SOCKET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#define SOCKET_BUF_SIZE 1500
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int init_unix_socket(const char* file_name);
|
||||
int unix_socket_send(int sockfd, struct sockaddr_un *dest_un, const char*data, int datalen);
|
||||
int init_recv_udp_socket(uint16_t port);
|
||||
int recv_udp_socket_recv(int sockfd, uint32_t *src_ip, uint8_t *buf, uint32_t buf_size);
|
||||
int init_recv_unix_socket(const char* file_name);
|
||||
int recv_unix_socket_recv(int sockfd,char*buf,int buf_len);
|
||||
int init_send_udp_socket();
|
||||
int send_udp_socket_send(int sockfd, uint32_t addr, uint16_t port, char *data, int datalen);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
113
src/inc/queue.h
Normal file
113
src/inc/queue.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/***************************************************
|
||||
* TAILQ int Linux's <sys/queue.h>
|
||||
****************************************************/
|
||||
|
||||
|
||||
#ifndef _QUEUE_H_
|
||||
#define _QUEUE_H_
|
||||
|
||||
/**
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define _TAILQ_HEAD(name, type, qual) \
|
||||
struct name { \
|
||||
qual type *tqh_first; /* first element */ \
|
||||
qual type *qual *tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define _TAILQ_ENTRY(type, qual) \
|
||||
struct { \
|
||||
qual type *tqe_next; /* next element */ \
|
||||
qual type *qual *tqe_prev; /* address of previous next element */\
|
||||
}
|
||||
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||
if (!TAILQ_EMPTY(head2)) { \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
46
src/inc/sifter.h
Normal file
46
src/inc/sifter.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _SIFTER_H
|
||||
#define _SIFTER_H
|
||||
|
||||
|
||||
#ifndef U_INT32_H
|
||||
#define U_INT32_H
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
|
||||
|
||||
typedef void* sifter_t;
|
||||
|
||||
typedef struct expect_outcome_s
|
||||
{
|
||||
char* data; //not copy, only point to text
|
||||
int datalen;
|
||||
}expect_outcome_t;
|
||||
|
||||
#define TEXT_NAME_LEN 32
|
||||
typedef struct text_s
|
||||
{
|
||||
char* text;
|
||||
char text_name[TEXT_NAME_LEN];
|
||||
uint32 text_len;
|
||||
uchar text_type;
|
||||
}text_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//file dir, all file is *.sft.
|
||||
sifter_t create_sifter(const char* sifter_cfg_dir, const char* sifter_log_dir, int maat_stat_swicth, int maat_perf_swicth, int thread_num, void* logger);
|
||||
void destroy_sifter(sifter_t handle);
|
||||
//return:res num;
|
||||
int sifter(sifter_t handle, int sftid,
|
||||
int expect_type, const char* expect_name, int expect_res_num, expect_outcome_t* res,
|
||||
const text_t* text, int text_num, const char* cont_type, unsigned int cont_type_len, int thread_seq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
100
src/inc/soqav_dedup.h
Normal file
100
src/inc/soqav_dedup.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef __SOQ_AV_DEDUPLICATION_H__
|
||||
#define __SOQ_AV_DEDUPLICATION_H__
|
||||
|
||||
#include "stream.h"
|
||||
#include "interval_index.h"
|
||||
|
||||
#define BIT_TD_KNOWN 1
|
||||
#define BIT_TD_MULTI_SOURCE 2
|
||||
|
||||
typedef struct __htable_opt
|
||||
{
|
||||
unsigned int htable_num;
|
||||
int htable_exp_time;
|
||||
}htable_opt_t;
|
||||
|
||||
typedef struct __addr_node{
|
||||
unsigned int ip_nr; //network order
|
||||
unsigned short port_nr; //network order
|
||||
}addr_node_t ;
|
||||
|
||||
typedef struct __query_detail
|
||||
{
|
||||
unsigned long long mid;
|
||||
unsigned long total_len; //<2F><>Ŀ<EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
|
||||
const char *url;
|
||||
const char *other; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD>ԴTD<54>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||
unsigned int urllen;
|
||||
unsigned int otherlen;
|
||||
union
|
||||
{
|
||||
struct stream_tuple4_v4 *tuple4_v4;
|
||||
struct stream_tuple4_v6 *tuple4_v6;
|
||||
};
|
||||
unsigned char addrtype; //ADDR_TYPE_IPV4/* 1, <20><><EFBFBD><EFBFBD>IPv4<76><34>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>Ϣ */ADDR_TYPE_IPV6,/* 2, <20><><EFBFBD><EFBFBD>IPv6<76><36>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>Ϣ */
|
||||
}query_detail_t;
|
||||
|
||||
//TODO
|
||||
typedef struct __scan_detail
|
||||
{
|
||||
long long config_id;
|
||||
}scan_detail_t;
|
||||
|
||||
typedef struct __report_detail
|
||||
{
|
||||
unsigned long long mid;
|
||||
scan_detail_t *scan_detail; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
unsigned long current_len; //<2F><>ǰ<EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||||
unsigned long total_len; //<2F><>Ŀ<EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
|
||||
union
|
||||
{
|
||||
struct stream_tuple4_v4 *tuple4_v4;
|
||||
struct stream_tuple4_v6 *tuple4_v6;
|
||||
};
|
||||
IVI_t *ivi_handle;
|
||||
const char *file_sfh;
|
||||
const char *url;
|
||||
const char *other; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD>ԴTD<54>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||
unsigned int sfh_len;
|
||||
unsigned int urllen;
|
||||
unsigned int otherlen;
|
||||
unsigned char addrtype; //ADDR_TYPE_IPV4/* 1, <20><><EFBFBD><EFBFBD>IPv4<76><34>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>Ϣ */ADDR_TYPE_IPV6,/* 2, <20><><EFBFBD><EFBFBD>IPv6<76><36>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>Ϣ */
|
||||
}report_detail_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEDUP_TYPE_BALANCE_NUM, //unsgined int<6E><74><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><F3BCB6A3><EFBFBD><EFBFBD>и<EFBFBD><D0B8>ؾ<EFBFBD><D8BE>⣬Ĭ<E2A3AC><C4AC>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ѯ2000<30>Σ<EFBFBD>
|
||||
DEDUP_TYPE_QUEUE_NUM, //unsgined int<6E><74><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>ϱ<EFBFBD><CFB1>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>100000<30><30>
|
||||
DEDUP_TYPE_STAT_INTERVAL, //unsigned int<6E><74><EFBFBD>ͣ<EFBFBD>Ĭ<EFBFBD><C4AC>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>300<30>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>
|
||||
DEDUP_TYPE_THRIFT_TIME, //unsigned int<6E><74><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>THRIFT<46><54>ʱʱ<CAB1>䣬<EFBFBD><E4A3AC>λ<EFBFBD><CEBB><EFBFBD>롣Ĭ<EBA1A3><C4AC>5s
|
||||
DEDUP_TYPE_HTABLE_ARG, //htable_opt_t<5F><74><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD>Ĺ<EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>1048576<37><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1>3600s
|
||||
}DEDUP_OPT_TYPE_t;
|
||||
|
||||
typedef void * soqav_dedup_handle_t;
|
||||
|
||||
typedef struct __query_result
|
||||
{
|
||||
int status; //status & BIT_TD_KNOWN<57><4E><EFBFBD><EFBFBD>Ŀ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>status & BIT_TD_MULTI_SOURCE<43><45><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>
|
||||
int cpz_mg_ip; //<2F><>Ҫע<D2AA><D7A2><EFBFBD><EFBFBD>Դʱ<D4B4><CAB1><EFBFBD><EFBFBD>ƴװIP<49><50>ַ<EFBFBD>DZ<EFBFBD><C7B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16777343(127.0.0.1)
|
||||
int cpz_payload_ip; //<2F><>Ҫע<D2AA><D7A2><EFBFBD><EFBFBD>Դʱ<D4B4><CAB1><EFBFBD><EFBFBD>ƴװIP<49><50>ַ<EFBFBD>DZ<EFBFBD><C7B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16777343(127.0.0.1)
|
||||
int reserve; //Ԥ<><D4A4>
|
||||
long long mid; //mid: <20><>Դʱ<D4B4><CAB1><EFBFBD><EFBFBD>Ŀ<EFBFBD>״γ<D7B4><CEB3>ֵ<EFBFBD>mid
|
||||
}query_result_t;
|
||||
|
||||
//user_arg: <20>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD>
|
||||
typedef long soqav_query_callback_t(const char *td, const query_result_t *result, void *user_arg);
|
||||
|
||||
extern "C" int soqav_dedup_set_opt(soqav_dedup_handle_t handle, DEDUP_OPT_TYPE_t type, const void *value, int size);
|
||||
//local_ifname<6D><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD>ڻش<DABB><D8B4><EFBFBD><EFBFBD><EFBFBD>IP<49><50>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD>
|
||||
extern "C" soqav_dedup_handle_t soqav_dedup_plug_init(addr_node_t *addr_array, unsigned int addr_num, int mg_ip, int payload_ip, unsigned int thread_num, void *handle_log);
|
||||
extern "C" void soqav_dedup_plug_destroy(soqav_dedup_handle_t handle);
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>TDΪNULL<4C><4C><EFBFBD><EFBFBD>ʾֻ<CABE><D6BB>ѯ<EFBFBD><D1AF>Դ<EFBFBD><D4B4>
|
||||
//<2F><>Դ<EFBFBD><D4B4>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>soqav_dedup_report<72><74><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>Դ<EFBFBD>Ľ<EFBFBD>Ŀһ<C4BF><D2BB>Ҫ<EFBFBD><D2AA>ѯ<EFBFBD><D1AF>
|
||||
extern "C" int soqav_dedup_query(soqav_dedup_handle_t handle, const char *td, const query_detail_t *detail, soqav_query_callback_t *callback_fun, void *user_arg);
|
||||
|
||||
//soqav_dedup_reportֻ<74><D6BB><EFBFBD><EFBFBD>ȥ<EFBFBD>أ<EFBFBD><D8A3>ظ<EFBFBD><D8B8>Ľ<EFBFBD>Ŀ<EFBFBD><C4BF>Ҫ<EFBFBD>ϱ<EFBFBD>
|
||||
extern "C" int soqav_dedup_report(soqav_dedup_handle_t handle, const char *td, const report_detail_t *detail);
|
||||
|
||||
#endif
|
||||
|
||||
85
src/inc/stream_fuzzy_hash.h
Normal file
85
src/inc/stream_fuzzy_hash.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef _MESA_FUZZY_
|
||||
#define _MESA_FUZZY_
|
||||
|
||||
/*
|
||||
* Copyright (C) MESA 2015
|
||||
*
|
||||
* These functions allow a programmer to compute the fuzzy hashes
|
||||
* (also called the context-triggered piecewise hashes) of
|
||||
* buffer[s] of text.
|
||||
*
|
||||
* See also:
|
||||
* ssdeep, and
|
||||
* Identifying almost identical files using context triggered piecewise hashing
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TOTAL_LENGTH 0
|
||||
#define EFFECTIVE_LENGTH 1
|
||||
#define HASH_LENGTH 2
|
||||
|
||||
// typedef sfh_instance_t void*;
|
||||
typedef struct
|
||||
{
|
||||
}sfh_instance_t;
|
||||
|
||||
/**
|
||||
* create a fuzzy hash handle and return it.
|
||||
* @return [handle]
|
||||
*/
|
||||
sfh_instance_t * SFH_instance(unsigned long long origin_len);
|
||||
|
||||
/**
|
||||
* destroy context by a fuzzy hash handle.
|
||||
* @param handle [handle]
|
||||
*/
|
||||
void SFH_release(sfh_instance_t * handle);
|
||||
|
||||
/**
|
||||
* Feed the function your data.
|
||||
* Call this function several times, if you have several parts of data to feed.
|
||||
* @param handle [handle]
|
||||
* @param data [data that you want to fuzzy_hash]
|
||||
* @param size [data size]
|
||||
* @param offset [offset]
|
||||
* @return [return effective data length in current feed]
|
||||
*/
|
||||
unsigned int SFH_feed(sfh_instance_t * handle, const char* data, unsigned int size, unsigned long long offset);
|
||||
|
||||
/**
|
||||
* Obtain the fuzzy hash values.
|
||||
* @param handle [handle]
|
||||
* @param result [fuzzy hash result]
|
||||
* Fuzzy hash result with offsets(in the square brackets, with colon splitted).
|
||||
* eg. abc[1:100]def[200:300]
|
||||
* @param size [@result size]
|
||||
* @return [return zero on success, non-zero on error]
|
||||
*/
|
||||
int SFH_digest(sfh_instance_t * handle, char* result, unsigned int size);
|
||||
|
||||
/**
|
||||
* Obtain certain length of fuzzy hash status.
|
||||
* @param handle [handle]
|
||||
* @param type [length type]
|
||||
* TOTAL_LENGTH:Total length of data you have fed.
|
||||
* Overlapped data will NOT count for 2 times.
|
||||
* EFFECTIVE_LENGTH:Length of data that involved in the calculation of hash.
|
||||
* HASH_LENGTH:Hash result length.
|
||||
* @return [length value]
|
||||
*/
|
||||
unsigned long long SFH_status(sfh_instance_t * handle, int type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
78
src/inc/usm_api.h
Normal file
78
src/inc/usm_api.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* usm_api.h
|
||||
*
|
||||
* Created on: 2017-1-17
|
||||
* Author: dmj
|
||||
*/
|
||||
#ifndef __USM_COMM_H_INCLUDE_
|
||||
#define __USM_COMM_H_INCLUDE_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef uint64_t
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
#ifndef uint16_t
|
||||
typedef unsigned int uint16_t;
|
||||
#endif
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
}USM_t;
|
||||
|
||||
#define USM_READER 0x01
|
||||
#define USM_WRITER 0x02
|
||||
|
||||
enum USM_rst_t
|
||||
{
|
||||
USM_SUCC = 0,
|
||||
USM_RD_SHMGET_ERR = -1,
|
||||
USM_SHMCTL_ERR = -2,
|
||||
USM_WT_SHMGET_ERR = -3,
|
||||
USM_SHMAT_ERR = -4,
|
||||
USM_SOCKET_INIT_ERR = -5,
|
||||
USM_QUEUE_INIT_ERR = -6
|
||||
};
|
||||
|
||||
enum USM_opt_t
|
||||
{
|
||||
SHM_BUF_SIZE,//WRITER and READER VIEW.VALUE is interger,SIZE=sizeof(int). DEFAULT:65535.
|
||||
READER_CNT,//WRITER VIEW.
|
||||
SMOOTH_TIME,//WRITER VIEW.but every reader need to set
|
||||
READER_ID,//READER VIEW.VALUE is interger,SIZE=sizeof(int). 0-7.Reader needs set read_id first.
|
||||
MAX_LQUEUE_SIZE,//READER VIEW.VALUE is interger,SIZE=sizeof(int). DEFAULT:1500.
|
||||
READER_PATH,//READER VIEW.data is a const char* und_path, define the reader's Unix named domain socket file path. return reader id if success.
|
||||
LOG_HANDLE
|
||||
};
|
||||
|
||||
enum USM_stat_t
|
||||
{
|
||||
WRITED_SIZE,
|
||||
WRITED_CNT,
|
||||
WRITING_CLASH_SIZE,
|
||||
WRITING_CLASH_CNT,
|
||||
SENDED_CNT, //READERS
|
||||
READED_SIZE,
|
||||
READED_CNT,
|
||||
READER_DROP_SIZE,//number of reader missed due to overwrite
|
||||
READER_DROP_CNT,
|
||||
READING_CLASH_SIZE,
|
||||
READING_CLASH_CNT,
|
||||
LQ_COUNT
|
||||
};
|
||||
|
||||
USM_t* USM_handle(int shm_key,uint64_t shm_size,int role);
|
||||
int USM_init(USM_t* handle);
|
||||
int USM_write(USM_t* handle,const char* data,int datalen);
|
||||
int USM_read(USM_t* handle,char** data,int* datalen,int* data_cnt);
|
||||
int USM_set_opt(USM_t* handle,enum USM_opt_t type,void* data,int size,int reader_id);
|
||||
uint64_t USM_stat(USM_t* handle,enum USM_stat_t type,int reader_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
69
src/inc/wiredLB.h
Normal file
69
src/inc/wiredLB.h
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
/*
|
||||
*****************Wired Load Balancer********
|
||||
* Load balance form producer to the consumer.
|
||||
* Cooperate with consul, which is a service discovery infrastructure.
|
||||
* See document for detail instructions.
|
||||
* Author: zhengchao@iie.ac.cn, MESA
|
||||
* All right reserved by www.mesalab.cn 2018~2021
|
||||
*********************************************************
|
||||
*/
|
||||
|
||||
#ifndef H_WIRED_LOAD_BALANCER_H_INCLUDE
|
||||
#define H_WIRED_LOAD_BALANCER_H_INCLUDE
|
||||
#include <stddef.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define WLB_CONSUMER 0
|
||||
#define WLB_PRODUCER 1
|
||||
#define WLB_MAX_TAG_SIZE 1024
|
||||
#define ADDRSRLEN_MAX 46
|
||||
|
||||
enum WLB_OPTION
|
||||
{
|
||||
WLB_OPT_ENABLE_OVERRIDE=0, // VALUE is an int, 1 for enable, 0 for disable. DEFAULT: 0.
|
||||
WLB_OPT_HEALTH_CHECK_PORT, // VALUE is a short int, SIZE=sizeof(short int). DEFAULT:52100.
|
||||
WLB_OPT_HEALTH_CHECK_INTERVAL, // VALUE is a short int, SIZE=sizeof(short int). DEFAULT:10 seconds.
|
||||
WLB_CONS_OPT_DATA_PORT, // VALUE is an unsigned short, SIZE=sizeof(unsigned short). DEFAULT: 0.
|
||||
WLB_CONS_OPT_PRIMARY_ADDR, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: use consul agent listen address.
|
||||
WLB_CONS_OPT_SECONDARY_ADDR, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: no default.
|
||||
WLB_CONS_OPT_CAPACITY, // VALUE is an int that range from 1 to 100, SIZE=sizeof(int). DEFAULT: 32.
|
||||
WLB_CONS_OPT_COST, // VALUE is an int that range from 1 to 100, SIZE=sizeof(int). DEFAULT: 32.
|
||||
WLB_CONS_OPT_USER_TAG, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null". Size must Not exceed WLB_MAX_TAG_SIZE.
|
||||
WLB_PROD_OPT_OVERRIDE_PRIMARY_IP, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null", format: "10.2.0.1-250;123.57.35.100-250;"
|
||||
WLB_PROD_OPT_OVERRIDE_SECONDARY_IP, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null", same format as WLB_PROD_OPT_OVERRIDE_PRIMARY_IP.
|
||||
WLB_PROD_OPT_OVERRIDE_DATAPORT, // VALUE is an unsigned short, SIZE=sizeof(unsigned short). DEFAULT: 0.
|
||||
WLB_PROD_OPT_OVERRIDE_USER_TAG // Same requirement as WLB_CONS_OPT_USER_TAG.
|
||||
};
|
||||
typedef void* WLB_handle_t;
|
||||
|
||||
struct WLB_consumer_t
|
||||
{
|
||||
char ip_addr[ADDRSRLEN_MAX];
|
||||
unsigned short data_port;
|
||||
char user_tag[WLB_MAX_TAG_SIZE];
|
||||
};
|
||||
// Lookup is THREAD SAFE.
|
||||
int wiredLB_lookup(WLB_handle_t handle, const void* key, int len, struct WLB_consumer_t* consumer);
|
||||
|
||||
int wiredLB_list(WLB_handle_t handle,size_t n_cons, struct WLB_consumer_t* cons_array);
|
||||
|
||||
|
||||
//Report is THREAD SAFE, NULL is allowed for runtime_info.
|
||||
void wiredLB_report(WLB_handle_t handle,long proc_bytes, long proc_count, const char* runtime_info);
|
||||
|
||||
//[IN] topic, MADATORY, use utf-8 for non English character.
|
||||
//[IN] group_name, OPTIONALl, could be NULL, use utf-8 for non English character.
|
||||
//[IN] role, WLB_COSUMER or WLB_PRODUCER
|
||||
WLB_handle_t wiredLB_create(const char* topic, const char* group_name, int role);
|
||||
int wiredLB_set_opt(WLB_handle_t handle, enum WLB_OPTION opt, const void* value, size_t size);
|
||||
int wiredLB_init(WLB_handle_t handle);
|
||||
void wiredLB_destroy(WLB_handle_t handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
39
src/inc/wired_cfg.h
Normal file
39
src/inc/wired_cfg.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef H_WIRED_CFG_H_INCLUDE
|
||||
#define H_WIRED_CFG_H_INCLUDE
|
||||
#include <stddef.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define WCFG_RET_ERR -1
|
||||
#define WCFG_RET_NOT_EXIST 0
|
||||
#define WCFG_RET_OK 1
|
||||
|
||||
enum WCFG_OPTION
|
||||
{
|
||||
LOCAL_ONLY=0,
|
||||
REMOTE_TIMEOUT,
|
||||
DCFG_ERR
|
||||
};
|
||||
|
||||
void * wired_cfg_create(const char* app_name, const char* cfg_path);
|
||||
|
||||
// return DCFG_RET_xx
|
||||
int wired_cfg_set_opt(void*handle, enum WCFG_OPTION option, const char* val, size_t size);
|
||||
|
||||
// return DCFG_RET_xx
|
||||
int wired_cfg_init(void* handle);
|
||||
|
||||
// convert the value as your own wish with sscanf
|
||||
// handle [IN] which aquired by wired_cfg_create
|
||||
// section [IN] section name in initialization file
|
||||
// key [IN] keyword name in initialization file
|
||||
// value [OUT] returned string
|
||||
// size [IN] buffer size(bytes)
|
||||
//default_value[IN] default string
|
||||
int wired_cfg_read(void*handle, const char* section, const char* key,char* value, size_t size,const char* default_value);
|
||||
|
||||
void wired_cfg_destroy(void* handle);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
BIN
src/lib/libMESA_trace.a
Normal file
BIN
src/lib/libMESA_trace.a
Normal file
Binary file not shown.
BIN
src/lib/lib_MESA_timer.a
Normal file
BIN
src/lib/lib_MESA_timer.a
Normal file
Binary file not shown.
BIN
src/lib/lib_interval_index.a
Normal file
BIN
src/lib/lib_interval_index.a
Normal file
Binary file not shown.
BIN
src/lib/libbusinessman.a
Normal file
BIN
src/lib/libbusinessman.a
Normal file
Binary file not shown.
BIN
src/lib/libdictator_debug.a
Normal file
BIN
src/lib/libdictator_debug.a
Normal file
Binary file not shown.
BIN
src/lib/libhiredis_vip.a
Normal file
BIN
src/lib/libhiredis_vip.a
Normal file
Binary file not shown.
BIN
src/lib/libmy_socket.a
Normal file
BIN
src/lib/libmy_socket.a
Normal file
Binary file not shown.
BIN
src/lib/libsifter.a
Normal file
BIN
src/lib/libsifter.a
Normal file
Binary file not shown.
BIN
src/lib/usm_comm.a
Normal file
BIN
src/lib/usm_comm.a
Normal file
Binary file not shown.
484
src/log.c
Normal file
484
src/log.c
Normal file
@@ -0,0 +1,484 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "MESA_htable.h"
|
||||
|
||||
#include "field_stat2.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
#include "log.h"
|
||||
#include "main.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
extern frag_reassembly_t frag_rssb;
|
||||
|
||||
void get_queuelog_count()
|
||||
{
|
||||
uint32_t i=0;
|
||||
g_frag_stat.sysinfo_stat[BIZMAN_RECV_QUEUE][QUEUE_CURRENT]=0;
|
||||
g_frag_stat.sysinfo_stat[APP_QUEUE][QUEUE_CURRENT]=0;
|
||||
g_frag_stat.sysinfo_stat[DUMPFILE_QUEUE][QUEUE_CURRENT]=0;
|
||||
g_frag_stat.sysinfo_stat[AV_RECORD_QUEUE][QUEUE_CURRENT]=0;
|
||||
g_frag_stat.sysinfo_stat[AV_DIGEST_RECORD_QUEUE][QUEUE_CURRENT]=0;
|
||||
if(g_frag_cfg.bizman_queue_mode)
|
||||
{
|
||||
for(i=0;(g_frag_cfg.bizman_queue_mode && i<g_frag_cfg.thread_num);i++)
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[BIZMAN_RECV_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(g_frag_run.recv_bizman_lq[i]);
|
||||
}
|
||||
}
|
||||
if(g_frag_cfg.app_switch)
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[APP_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(g_frag_run.app_lq);
|
||||
}
|
||||
if(g_frag_cfg.monitor_file_switch)
|
||||
{
|
||||
for(i=0;i<g_frag_cfg.thread_num;i++)
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[DUMPFILE_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(g_frag_run.monitor_file_lq[i]);
|
||||
}
|
||||
}
|
||||
if(g_frag_cfg.avrecord_switch)
|
||||
{
|
||||
for(i=0;i<g_frag_cfg.thread_num;i++)
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[AV_RECORD_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(g_frag_run.av_record_lq[i]);
|
||||
}
|
||||
for(i=0;i<g_frag_cfg.thread_num;i++)
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[AV_DIGEST_RECORD_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(g_frag_run.av_digest_record_lq[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_hashlog_count()
|
||||
{
|
||||
g_frag_stat.sysinfo_stat[MONITOR_HASH][HASH_CURRENT] = MESA_htable_get_elem_num(g_frag_run.media_monitor_hash);
|
||||
g_frag_stat.sysinfo_stat[DUMPFILE_HASH][HASH_CURRENT] = MESA_htable_get_elem_num(g_frag_run.dumpfile_hash);
|
||||
g_frag_stat.sysinfo_stat[MEDIA_HASH][HASH_CURRENT] = MESA_htable_get_elem_num(g_frag_run.media_hash);
|
||||
}
|
||||
|
||||
void* thread_sysinfo_output(void *param)
|
||||
{
|
||||
g_frag_stat.syslog_column_id[NUM_CUR] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_cur(hash_cur)");
|
||||
g_frag_stat.syslog_column_id[NUM_IN] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_in(hash_num_expire)");
|
||||
g_frag_stat.syslog_column_id[NUM_OUT] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_out(hash_time_expire)");
|
||||
|
||||
|
||||
g_frag_stat.syslog_line_id[BIZMAN_RECV_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"bizman_queue");
|
||||
g_frag_stat.syslog_line_id[MULTISRC_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"multi_queue");
|
||||
g_frag_stat.syslog_line_id[APP_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"app_queue");
|
||||
g_frag_stat.syslog_line_id[DUMPFILE_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"dumpfile_queue");
|
||||
g_frag_stat.syslog_line_id[AV_RECORD_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"av_record_queue");
|
||||
g_frag_stat.syslog_line_id[AV_DIGEST_RECORD_QUEUE] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"av_digest_record_queue");
|
||||
g_frag_stat.syslog_line_id[MONITOR_HASH] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"monitor_hash");
|
||||
g_frag_stat.syslog_line_id[DUMPFILE_HASH] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"dumpfile_hash");
|
||||
g_frag_stat.syslog_line_id[MEDIA_HASH] = FS_register(g_frag_stat.sysfs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"media_hash");
|
||||
|
||||
FS_start(g_frag_stat.sysfs_handle);
|
||||
uint32_t i=0, j=0;
|
||||
while(g_frag_stat.sysinfo_interval>0)
|
||||
{
|
||||
sleep(g_frag_stat.sysinfo_interval);
|
||||
get_queuelog_count();
|
||||
get_hashlog_count();
|
||||
for(i=0;i<SYSLOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
for(j=0;j<SYSLOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
FS_operate(g_frag_stat.sysfs_handle, g_frag_stat.syslog_line_id[i],g_frag_stat.syslog_column_id[j],FS_OP_SET, g_frag_stat.sysinfo_stat[i][j]);
|
||||
}
|
||||
}
|
||||
FS_passive_output(g_frag_stat.sysfs_handle);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void* thread_stat_output(void *param)
|
||||
{
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_CREATE] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"create_media");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_RENEW] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"renew_media");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_EXPIRE] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"expire_media");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_OUTPUT] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"output_media");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_HTTP] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"media_http");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_OFFSET_ZERO] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"media_offset_0");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_QUERY] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"dedup_query");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_TD_QUERY] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"TD_query");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_ACK] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"dedup_ack");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"media_dedup");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_MULTI] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"media_multi");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_ACK_TIMEOUT] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"ack_timeout");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_TIMEOUT] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"dedup_timeout");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_REPORT] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"dedup_report_all");
|
||||
g_frag_stat.log_field_id[LOG_MEDIA_DEDUP_REPORT_COMPLETE] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"dedup_report_normal");
|
||||
g_frag_stat.log_field_id[LOG_AV_RECORD] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"AV_record");
|
||||
g_frag_stat.log_field_id[LOG_AV_DIGEST_RECORD] = FS_register(g_frag_stat.fs_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"AV_digest_record");
|
||||
|
||||
g_frag_stat.log_column_id[TOTAL_PKTS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"total_pkts");
|
||||
g_frag_stat.log_column_id[TOTAL_BYTES] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"total_len");
|
||||
g_frag_stat.log_column_id[PPS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"pps");
|
||||
g_frag_stat.log_column_id[BPS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"Bps");
|
||||
g_frag_stat.log_column_id[FAIL_PKTS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"fail_pkts");
|
||||
g_frag_stat.log_column_id[FAIL_BYTES] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"fail_len");
|
||||
g_frag_stat.log_column_id[FAIL_PPS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"fail_pps");
|
||||
g_frag_stat.log_column_id[FAIL_BPS] = FS_register(g_frag_stat.fs_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"fail_Bps");
|
||||
|
||||
g_frag_stat.log_line_id[RECV]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"all_recv");
|
||||
g_frag_stat.log_line_id[RECV_DROP]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_drop");
|
||||
g_frag_stat.log_line_id[INVALID_RECV]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"invalid_recv");
|
||||
g_frag_stat.log_line_id[META_RECV]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"meta_recv");
|
||||
g_frag_stat.log_line_id[DATA_RECV]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"data_recv");
|
||||
g_frag_stat.log_line_id[OTHER_RECV]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"other_recv");
|
||||
g_frag_stat.log_line_id[MEDIA_NOMETA]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"media_nometa");
|
||||
g_frag_stat.log_line_id[RESP_UNRECOGNIZED]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"unknow_response_msg");
|
||||
g_frag_stat.log_line_id[RESP_CHARACTER]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"resp_character");
|
||||
|
||||
g_frag_stat.log_line_id[INVALID_RESP_CHECKRESULT]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"invalid_response_msg");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"normal_response_msg");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_WHITELIST_IN]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"whitelist_recv");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_recv");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN_NOFOUND]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_nofound");
|
||||
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_VOIP_FULLLOG]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"voip_fulllog");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_VOIP_SURVEYLOG]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"voip_surveylog");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN_REPEAT]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_repeat");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN_MONITOR_LEVEL1]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_monitor_1");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN_MONITOR_LEVEL2]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_monitor_2");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_FRAG_SURVEY]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"frag_survey");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_INDEX_SURVEY]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"index_survey");
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_IN_BLOCK]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"blocklist_block");
|
||||
|
||||
g_frag_stat.log_line_id[INVALID_RESP_PROG_SYNC]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"invalid_prog_sync");
|
||||
g_frag_stat.log_line_id[RESP_PROG_SYNC]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"normal_prog_sync");
|
||||
g_frag_stat.log_line_id[RESP_PROG_SYNC_IN_NOFOUND]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"sync_prog_nofound");
|
||||
g_frag_stat.log_line_id[RESP_PROG_SYNC_AUDIO]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"prog_sync_audio");
|
||||
g_frag_stat.log_line_id[RESP_PROG_SYNC_VIDEO]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"prog_sync_video");
|
||||
|
||||
g_frag_stat.log_line_id[RESP_CHECKRESULT_BLACKLIST_OUT_BLOCK]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"block_to_qd");
|
||||
g_frag_stat.log_line_id[AUDIO_LANG_MONITOR_OUT]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"monitor_audio_lang");
|
||||
g_frag_stat.log_line_id[CONFIG_MONITOR_OUT]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"monitor_config");
|
||||
g_frag_stat.log_line_id[MONITOR_DUMP_FILE]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"monitor_dumpfile");
|
||||
|
||||
g_frag_stat.log_line_id[RESP_CHARACTER_ACK]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"prog_ack");
|
||||
|
||||
g_frag_stat.log_line_id[TO_SEND]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"to_send");
|
||||
g_frag_stat.log_line_id[FRAG_DEDUP]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"frag_dedup");
|
||||
g_frag_stat.log_line_id[DEDUP_DROP]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"dedup_drop");
|
||||
g_frag_stat.log_line_id[WAIT_QUEUE_FULL_DROP]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"waitlq_fulldrop");
|
||||
g_frag_stat.log_line_id[SRC_SEND_LOCAL]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"send_local");
|
||||
g_frag_stat.log_line_id[SRC_SEND_CPZ]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"send_cpz");
|
||||
g_frag_stat.log_line_id[SRC_WINS_SEND]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"send_wins");
|
||||
g_frag_stat.log_line_id[MEDIA_JSON]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"media_json");
|
||||
g_frag_stat.log_line_id[SURVEY_JSON]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"survey_json");
|
||||
|
||||
|
||||
char buf[32] = {0};
|
||||
int send_dest_num = 0;
|
||||
#if K_PROJECT
|
||||
send_dest_num = g_frag_cfg.send_dest_udp_ip_num;
|
||||
for(uint32_t m=0;m<g_frag_cfg.send_dest_udp_ip_num;m++)
|
||||
{
|
||||
inet_ntop(AF_INET, &g_frag_cfg.send_dest_udp_iplist[m], buf, sizeof(buf));
|
||||
g_frag_stat.sendlog_line_id[2*m]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT, "udp_send");
|
||||
g_frag_stat.sendlog_line_id[2*m+1]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT, "lq_count");
|
||||
}
|
||||
#else
|
||||
send_dest_num = g_frag_cfg.send_dest_addr_num;
|
||||
for(uint32_t m=0;m<g_frag_cfg.send_dest_addr_num;m++)
|
||||
{
|
||||
g_frag_stat.sendlog_line_id[2*m]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT, (char*)g_frag_cfg.send_dest_addr[m].sun_path);
|
||||
g_frag_stat.sendlog_line_id[2*m+1]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT, "lq_count");
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for(uint32_t m=0;m<g_frag_cfg.special_media_wins_port_num;m++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%hu", ntohs(g_frag_cfg.special_media_wins_port[m]));
|
||||
g_frag_stat.wins_sendlog_line_id[m]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,buf);
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for(uint32_t m=0;m<g_frag_cfg.whitelist_addr_num;m++)
|
||||
{
|
||||
inet_ntop(AF_INET, &g_frag_cfg.whitelist_addr[m].sin_addr.s_addr, buf, sizeof(buf));
|
||||
g_frag_stat.whitelist_sendlog_line_id[m]=FS_register(g_frag_stat.fs_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"whitelist");
|
||||
}
|
||||
|
||||
FS_start(g_frag_stat.fs_handle);
|
||||
uint32_t i=0, j=0, k=0;
|
||||
while(g_frag_stat.stat_interval>0)
|
||||
{
|
||||
sleep(g_frag_stat.stat_interval);
|
||||
|
||||
for(i=0;i<MEDIALOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.log_field_id[i],0,FS_OP_SET, g_frag_stat.media_stat[i]);
|
||||
}
|
||||
|
||||
for(i=0;i<LOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
for(j=0,k=0;j<LOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
switch(j)
|
||||
{
|
||||
case PPS:
|
||||
k=TOTAL_PKTS;
|
||||
break;
|
||||
|
||||
case BPS:
|
||||
k=TOTAL_BYTES;
|
||||
break;
|
||||
|
||||
case FAIL_PPS:
|
||||
k=FAIL_PKTS;
|
||||
break;
|
||||
|
||||
case FAIL_BPS:
|
||||
k=FAIL_BYTES;
|
||||
break;
|
||||
|
||||
default:
|
||||
k=j;
|
||||
break;
|
||||
}
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.log_line_id[i],g_frag_stat.log_column_id[j],FS_OP_SET, g_frag_stat.stat_info[i][k]);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<send_dest_num;i++)
|
||||
{
|
||||
for(j=0,k=0;j<LOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
switch(j)
|
||||
{
|
||||
case PPS:
|
||||
k=TOTAL_PKTS;
|
||||
break;
|
||||
|
||||
case BPS:
|
||||
k=TOTAL_BYTES;
|
||||
break;
|
||||
|
||||
case FAIL_PPS:
|
||||
k=FAIL_PKTS;
|
||||
break;
|
||||
|
||||
case FAIL_BPS:
|
||||
k=FAIL_BYTES;
|
||||
break;
|
||||
|
||||
default:
|
||||
k=j;
|
||||
break;
|
||||
}
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.sendlog_line_id[2*i],g_frag_stat.log_column_id[j],FS_OP_SET, g_frag_stat.send_stat[i][k]);
|
||||
}
|
||||
}
|
||||
for(i=0;i<send_dest_num;i++)
|
||||
{
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.sendlog_line_id[2*i+1],g_frag_stat.log_column_id[TOTAL_PKTS],FS_OP_SET, g_frag_stat.send_lq_stat[i][TOTAL_PKTS]);
|
||||
}
|
||||
for(i=0;i<g_frag_cfg.special_media_wins_port_num;i++)
|
||||
{
|
||||
for(j=0,k=0;j<LOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
switch(j)
|
||||
{
|
||||
case PPS:
|
||||
k=TOTAL_PKTS;
|
||||
break;
|
||||
|
||||
case BPS:
|
||||
k=TOTAL_BYTES;
|
||||
break;
|
||||
|
||||
case FAIL_PPS:
|
||||
k=FAIL_PKTS;
|
||||
break;
|
||||
|
||||
case FAIL_BPS:
|
||||
k=FAIL_BYTES;
|
||||
break;
|
||||
|
||||
default:
|
||||
k=j;
|
||||
break;
|
||||
}
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.wins_sendlog_line_id[i],g_frag_stat.log_column_id[j],FS_OP_SET, g_frag_stat.wins_send_stat[i][k]);
|
||||
}
|
||||
}
|
||||
for(i=0;i<g_frag_cfg.whitelist_addr_num;i++)
|
||||
{
|
||||
for(j=0,k=0;j<LOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
switch(j)
|
||||
{
|
||||
case PPS:
|
||||
k=TOTAL_PKTS;
|
||||
break;
|
||||
|
||||
case BPS:
|
||||
k=TOTAL_BYTES;
|
||||
break;
|
||||
|
||||
case FAIL_PPS:
|
||||
k=FAIL_PKTS;
|
||||
break;
|
||||
|
||||
case FAIL_BPS:
|
||||
k=FAIL_BYTES;
|
||||
break;
|
||||
|
||||
default:
|
||||
k=j;
|
||||
break;
|
||||
}
|
||||
FS_operate(g_frag_stat.fs_handle, g_frag_stat.whitelist_sendlog_line_id[i],g_frag_stat.log_column_id[j],FS_OP_SET, g_frag_stat.whitelist_send_stat[i][k]);
|
||||
}
|
||||
}
|
||||
FS_passive_output(g_frag_stat.fs_handle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void get_rssb_queuelog_count()
|
||||
{
|
||||
/*cnvg queue and index queue is frag_unit, not gloabl*/
|
||||
frag_rssb.sysinfo_stat[RSSB_WAIT_QUEUE][QUEUE_CURRENT]=0;
|
||||
for(uint32_t i=0;i<g_frag_cfg.thread_num;i++)
|
||||
{
|
||||
frag_rssb.sysinfo_stat[RSSB_WAIT_QUEUE][QUEUE_CURRENT] += MESA_lqueue_get_count(frag_rssb.wait_lq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void get_rssb_hashlog_count()
|
||||
{
|
||||
frag_rssb.sysinfo_stat[RSSB_CNVG_HASH][HASH_CURRENT] = MESA_htable_get_elem_num(frag_rssb.converge_hash);
|
||||
}
|
||||
|
||||
void* thread_frag_rssb_sysinfo_output(void *param)
|
||||
{
|
||||
frag_rssb.syslog_column_id[NUM_CUR] = FS_register(frag_rssb.sysinfo_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_cur(hash_cur)");
|
||||
frag_rssb.syslog_column_id[NUM_IN] = FS_register(frag_rssb.sysinfo_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_in(hash_num_expire)");
|
||||
frag_rssb.syslog_column_id[NUM_OUT] = FS_register(frag_rssb.sysinfo_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"queue_out(hash_time_expire)");
|
||||
|
||||
frag_rssb.syslog_line_id[RSSB_CNVG_QUEUE]=FS_register(frag_rssb.sysinfo_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"cnvg_queue");
|
||||
frag_rssb.syslog_line_id[RSSB_INDEX_QUEUE]=FS_register(frag_rssb.sysinfo_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"index_queue");
|
||||
frag_rssb.syslog_line_id[RSSB_WAIT_QUEUE]=FS_register(frag_rssb.sysinfo_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"wait_queue");
|
||||
frag_rssb.syslog_line_id[RSSB_CNVG_HASH]=FS_register(frag_rssb.sysinfo_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"cnvg_hash");
|
||||
|
||||
FS_start(frag_rssb.sysinfo_handle);
|
||||
int i=0, j=0;
|
||||
while(frag_rssb.sysinfo_interval>0)
|
||||
{
|
||||
sleep(frag_rssb.sysinfo_interval);
|
||||
get_rssb_queuelog_count();
|
||||
get_rssb_hashlog_count();
|
||||
for(i=0;i<RSSB_SYSLOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
for(j=0;j<SYSLOG_STAT_MAXNUM;j++)
|
||||
{
|
||||
FS_operate(frag_rssb.sysinfo_handle, frag_rssb.syslog_line_id[i],frag_rssb.syslog_column_id[j],FS_OP_SET, frag_rssb.sysinfo_stat[i][j]);
|
||||
}
|
||||
}
|
||||
FS_passive_output(frag_rssb.sysinfo_handle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* thread_frag_rssb_stat_output(void *param)
|
||||
{
|
||||
frag_rssb.log_field_id[RSSB_CREATE_FRAG_UNIT] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"add_frag_unit");
|
||||
frag_rssb.log_field_id[RSSB_FREE_FRAG_UNIT] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"free_frag_unit");
|
||||
frag_rssb.log_field_id[RSSB_FRAG_UNIT_EXIST] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"frag_unit_exist");
|
||||
frag_rssb.log_field_id[RSSB_FRAG_UNIT_ERROR] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"free_frag_error");
|
||||
frag_rssb.log_field_id[RSSB_FRAG_FORECAST] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"frag_forecast");
|
||||
frag_rssb.log_field_id[RSSB_FRAG_FORECAST_OK] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"frag_forecast_ok");
|
||||
frag_rssb.log_field_id[RSSB_CNVG_ONCE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"cnvg_query_1_send");
|
||||
frag_rssb.log_field_id[RSSB_CNVG_TWICE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"cnvg_query_2_send");
|
||||
frag_rssb.log_field_id[RSSB_CNVG_ONCE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"cnvg_query_1_succ");
|
||||
frag_rssb.log_field_id[RSSB_CNVG_TWICE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"cnvg_query_2_succ");
|
||||
frag_rssb.log_field_id[RSSB_INDEX_ONCE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"index_query_1_send");
|
||||
frag_rssb.log_field_id[RSSB_INDEX_TWICE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"index_query_2_send");
|
||||
frag_rssb.log_field_id[RSSB_INDEX_ONCE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"index_query_1_succ");
|
||||
frag_rssb.log_field_id[RSSB_INDEX_TWICE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"index_query_2_succ");
|
||||
frag_rssb.log_field_id[RSSB_AV_ONCE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"av_query_1_send");
|
||||
frag_rssb.log_field_id[RSSB_AV_TWICE_QUERY_SEND] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"av_query_2_send");
|
||||
frag_rssb.log_field_id[RSSB_AV_ONCE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"av_query_1_succ");
|
||||
frag_rssb.log_field_id[RSSB_AV_TWICE_QUERY_RECV] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"av_query_2_succ");
|
||||
frag_rssb.log_field_id[RSSB_SIP_ACK_KEY1] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"sip_ack_key1");
|
||||
frag_rssb.log_field_id[RSSB_SIP_ACK_KEY2] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"sip_ack_key2");
|
||||
frag_rssb.log_field_id[RSSB_SIP_ACK_KEY3] = FS_register(frag_rssb.stat_handle,FS_STYLE_FIELD,FS_CALC_CURRENT,"sip_ack_key3");
|
||||
|
||||
frag_rssb.datalog_column_id[TOTAL_PKTS] = FS_register(frag_rssb.stat_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"total_media(pkt)");
|
||||
frag_rssb.datalog_column_id[TOTAL_BYTES] = FS_register(frag_rssb.stat_handle,FS_STYLE_COLUMN,FS_CALC_CURRENT,"total_bytes");
|
||||
frag_rssb.datalog_column_id[PPS] = FS_register(frag_rssb.stat_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"media/s(pkt/s)");
|
||||
frag_rssb.datalog_column_id[BPS] = FS_register(frag_rssb.stat_handle,FS_STYLE_COLUMN,FS_CALC_SPEED,"Bps");
|
||||
|
||||
frag_rssb.datalog_line_id[RSSB_RECV_OTHER_MEDIA] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_media");
|
||||
frag_rssb.datalog_line_id[RSSB_RECV_HLS_MEDIA] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_hls_media");
|
||||
frag_rssb.datalog_line_id[RSSB_HLS_TO_OTHER] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_hls_other");
|
||||
frag_rssb.datalog_line_id[RSSB_RECV_OSMF_MEDIA] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_osmf_media");
|
||||
frag_rssb.datalog_line_id[RSSB_OSMF_TO_OTHER] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_osmf_other");
|
||||
frag_rssb.datalog_line_id[RSSB_RECV_FRAG_MEDIA] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_frag_media");
|
||||
frag_rssb.datalog_line_id[RSSB_FRAG_TO_OTHER] = FS_register(frag_rssb.stat_handle,FS_STYLE_LINE,FS_CALC_CURRENT,"recv_frag_other");
|
||||
|
||||
|
||||
FS_start(frag_rssb.stat_handle);
|
||||
int i=0, j=0, k=0;
|
||||
while(frag_rssb.stat_interval>0)
|
||||
{
|
||||
sleep(frag_rssb.stat_interval);
|
||||
|
||||
for(i=0;i<RSSB_LOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
FS_operate(frag_rssb.stat_handle, frag_rssb.log_field_id[i],0,FS_OP_SET, frag_rssb.stat_info[i]);
|
||||
}
|
||||
|
||||
for(i=0;i<RSSB_DATALOG_TYPE_MAXNUM;i++)
|
||||
{
|
||||
for(j=0,k=0;j<=BPS;j++)
|
||||
{
|
||||
switch(j)
|
||||
{
|
||||
case PPS:
|
||||
k=TOTAL_PKTS;
|
||||
break;
|
||||
|
||||
case BPS:
|
||||
k=TOTAL_BYTES;
|
||||
break;
|
||||
|
||||
default:
|
||||
k=j;
|
||||
break;
|
||||
}
|
||||
FS_operate(frag_rssb.stat_handle, frag_rssb.datalog_line_id[i],frag_rssb.datalog_column_id[j],FS_OP_SET, frag_rssb.data_info[i][k]);
|
||||
}
|
||||
}
|
||||
FS_passive_output(frag_rssb.stat_handle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
318
src/log.h
Normal file
318
src/log.h
Normal file
@@ -0,0 +1,318 @@
|
||||
#ifndef _LOG_H
|
||||
#define _LOG_H
|
||||
|
||||
#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 410)
|
||||
#define atomic_inc(x) __sync_add_and_fetch((x),1)
|
||||
#define atomic_dec(x) __sync_sub_and_fetch((x),1)
|
||||
#define atomic_add(x,y) __sync_add_and_fetch((x),(y))
|
||||
#define atomic_sub(x,y) __sync_sub_and_fetch((x),(y))
|
||||
typedef long atomic_t;
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define atomic_read(x) __sync_add_and_fetch((x),0)
|
||||
#define atomic_set(x,y) __sync_lock_test_and_set((x),y)
|
||||
#else
|
||||
typedef long atomic_t;
|
||||
#define atomic_inc(x) ((*(x))++)
|
||||
#define atomic_dec(x) ((*(x))--)
|
||||
#define atomic_add(x,y) ((*(x))+=(y))
|
||||
#define atomic_sub(x,y) ((*(x))-=(y))
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define atomic_read(x) (*(x))
|
||||
#define atomic_set(x,y) ((*(x))=(y))
|
||||
#endif
|
||||
|
||||
/*********************************************debug log type***********************************/
|
||||
typedef enum
|
||||
{
|
||||
ADD_META=0,
|
||||
ADD_FRAG,
|
||||
ADD_FRAG_NOUSE,
|
||||
GET_META,
|
||||
GET_FRAG,
|
||||
ADD_FRAG_TO_CNVG_LQ,
|
||||
GET_FRAG_FROM_CNVG_LQ,
|
||||
ADD_FRAG_TO_INDEX_LQ,
|
||||
GET_FRAG_FROM_INDEX_LQ,
|
||||
ADD_FRAG_TO_WAIT_LQ,
|
||||
|
||||
ADD_FRAG_TO_TAILQ,
|
||||
ADD_FRAG_FROM_TAILQ,
|
||||
|
||||
ADD_FRAG_TO_APP_LQ,
|
||||
|
||||
MEDIA_NO_META,
|
||||
HLS_OSMF_REPEAT,
|
||||
SET_OFFSET,
|
||||
|
||||
APP_CHANGE_PID,
|
||||
|
||||
/*cnvg<76><67>ѯ*/
|
||||
SEND_CNVG_QUERY_1,
|
||||
RECV_CNVG_ACK_1,
|
||||
CNVG_QUERY_FAIL_1,
|
||||
|
||||
SEND_CNVG_QUERY_2,
|
||||
RECV_CNVG_ACK_2,
|
||||
CNVG_QUERY_FAIL_2,
|
||||
|
||||
CNVG_FAIL_PROC, /*<2A><>ѯ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊģ<CEAA><C4A3><EFBFBD><EFBFBD>ȡʧ<C8A1><CAA7>*/
|
||||
|
||||
/*AV<41><56>ѯ*/
|
||||
SEND_AV_QUERY_1,
|
||||
RECV_AV_ACK_1,
|
||||
AV_QUERY_FAIL_1,
|
||||
|
||||
SEND_AV_QUERY_2,
|
||||
RECV_AV_ACK_2,
|
||||
AV_QUERY_FAIL_2,
|
||||
|
||||
/*<2A><>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ*/
|
||||
SEND_INDEX_QUERY_1,
|
||||
RECV_INDEX_ACK_1,
|
||||
INDEX_QUERY_FAIL_1,
|
||||
|
||||
SEND_INDEX_QUERY_2,
|
||||
RECV_INDEX_ACK_2,
|
||||
INDEX_QUERY_FAIL_2,
|
||||
|
||||
INDEX_FAIL_PROC, /*<2A><>ѯ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊģ<CEAA><C4A3><EFBFBD><EFBFBD>ȡʧ<C8A1><CAA7>*/
|
||||
|
||||
/*VOIP<49><50>ѯ*/
|
||||
SEND_VOIP_QUERY_1,
|
||||
RECV_VOIP_ACK_1,
|
||||
VOIP_QUERY_FAIL_1,
|
||||
|
||||
SEND_VOIP_QUERY_2,
|
||||
RECV_VOIP_ACK_2,
|
||||
VOIP_QUERY_FAIL_2,
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD>*/
|
||||
SEND_AV_DEDUP_QUERY,
|
||||
RECV_AV_DEDUP_ACK,
|
||||
RECV_AV_DEDUP_ACK_KNOWN,
|
||||
RECV_AV_DEDUP_ACK_MULTI,
|
||||
AV_DEDUP_QUERY_TIMEOUT,
|
||||
AV_DEDUP_REPORT,
|
||||
|
||||
/*<2A><>ƬԤ<C6AC>棬<EFBFBD><E6A3AC><EFBFBD><EFBFBD>URL<52><4C>URL<52><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>*/
|
||||
FRAG_FORECAST_ERROR,
|
||||
}FRAG_LOG_TYPE;
|
||||
|
||||
/*********************************************stat log type***********************************/
|
||||
typedef enum
|
||||
{
|
||||
LOG_MEDIA_CREATE=0,
|
||||
LOG_MEDIA_RENEW,
|
||||
|
||||
LOG_MEDIA_EXPIRE,
|
||||
LOG_MEDIA_OUTPUT,
|
||||
|
||||
LOG_MEDIA_HTTP,
|
||||
LOG_MEDIA_OFFSET_ZERO,
|
||||
LOG_MEDIA_DEDUP_QUERY,
|
||||
LOG_MEDIA_TD_QUERY,
|
||||
LOG_MEDIA_DEDUP_ACK,
|
||||
LOG_MEDIA_DEDUP,
|
||||
LOG_MEDIA_MULTI,
|
||||
LOG_MEDIA_DEDUP_ACK_TIMEOUT,
|
||||
LOG_MEDIA_DEDUP_TIMEOUT,
|
||||
LOG_MEDIA_DEDUP_REPORT,
|
||||
LOG_MEDIA_DEDUP_REPORT_COMPLETE,
|
||||
|
||||
LOG_AV_RECORD,
|
||||
LOG_AV_DIGEST_RECORD,
|
||||
|
||||
MEDIALOG_TYPE_MAXNUM,
|
||||
}MEDIALOG_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/*recv data*/
|
||||
RECV=0,
|
||||
RECV_DROP,
|
||||
INVALID_RECV,
|
||||
META_RECV,
|
||||
DATA_RECV,
|
||||
OTHER_RECV,
|
||||
MEDIA_NOMETA,
|
||||
|
||||
/*recv response message*/
|
||||
RESP_UNRECOGNIZED,
|
||||
RESP_CHARACTER,
|
||||
|
||||
INVALID_RESP_CHECKRESULT,
|
||||
RESP_CHECKRESULT,
|
||||
RESP_CHECKRESULT_WHITELIST_IN, //resp msg whitelist : level = 0;
|
||||
RESP_CHECKRESULT_BLACKLIST_IN, //resp msg blacklist : level > 0;
|
||||
RESP_CHECKRESULT_BLACKLIST_IN_NOFOUND, //resp msg blacklist : level > 0; not found
|
||||
RESP_CHECKRESULT_VOIP_FULLLOG, //VOIP full log
|
||||
RESP_CHECKRESULT_VOIP_SURVEYLOG, //VOIP survey log
|
||||
RESP_CHECKRESULT_BLACKLIST_IN_REPEAT, //resp msg blacklist : level > 0; repeat
|
||||
RESP_CHECKRESULT_BLACKLIST_IN_MONITOR_LEVEL1, //resp msg blacklist : level > 0; monitor service, first
|
||||
RESP_CHECKRESULT_BLACKLIST_IN_MONITOR_LEVEL2, //resp msg blacklist : level > 0; monitor service, again
|
||||
RESP_CHECKRESULT_BLACKLIST_IN_BLOCK, //resp msg blacklist : level > 0; block service
|
||||
|
||||
RESP_CHECKRESULT_FRAG_SURVEY, //frag survey log
|
||||
RESP_CHECKRESULT_INDEX_SURVEY, //frag survey log include index
|
||||
|
||||
INVALID_RESP_PROG_SYNC,
|
||||
RESP_PROG_SYNC,
|
||||
RESP_PROG_SYNC_IN_NOFOUND,
|
||||
RESP_PROG_SYNC_AUDIO,
|
||||
RESP_PROG_SYNC_VIDEO,
|
||||
|
||||
/*send survey*/
|
||||
RESP_CHECKRESULT_BLACKLIST_OUT_BLOCK,
|
||||
AUDIO_LANG_MONITOR_OUT, //hit audio lang monitor service, send monitor
|
||||
CONFIG_MONITOR_OUT, //hit config monitor service,send monitor
|
||||
|
||||
/*dumpfile*/
|
||||
MONITOR_DUMP_FILE,
|
||||
|
||||
/*qd_ack*/
|
||||
RESP_CHARACTER_ACK,
|
||||
|
||||
/*to_send ~~ DEDUP_DROP+SRC_SEND*/
|
||||
TO_SEND,
|
||||
|
||||
FRAG_DEDUP,
|
||||
|
||||
/*dedup drop*/
|
||||
DEDUP_DROP,
|
||||
|
||||
/*wait drop*/
|
||||
WAIT_QUEUE_FULL_DROP,
|
||||
|
||||
/*send data*/
|
||||
SRC_SEND_LOCAL,
|
||||
SRC_SEND_CPZ,
|
||||
SRC_WINS_SEND,
|
||||
|
||||
/*json kafka*/
|
||||
MEDIA_JSON,
|
||||
SURVEY_JSON,
|
||||
|
||||
LOG_TYPE_MAXNUM,
|
||||
}LOG_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIZMAN_RECV_QUEUE=0,
|
||||
MULTISRC_QUEUE,
|
||||
APP_QUEUE,
|
||||
DUMPFILE_QUEUE,
|
||||
AV_RECORD_QUEUE,
|
||||
AV_DIGEST_RECORD_QUEUE,
|
||||
MONITOR_HASH,
|
||||
DUMPFILE_HASH,
|
||||
MEDIA_HASH,
|
||||
|
||||
SYSLOG_TYPE_MAXNUM,
|
||||
}SYSLOG_TYPE;
|
||||
|
||||
/*----------frag_reassembly---------------*/
|
||||
typedef enum
|
||||
{
|
||||
RSSB_CREATE_FRAG_UNIT=0, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䵥Ԫ
|
||||
RSSB_FREE_FRAG_UNIT,
|
||||
RSSB_FRAG_UNIT_EXIST,
|
||||
RSSB_FRAG_UNIT_ERROR,
|
||||
RSSB_FRAG_FORECAST,
|
||||
RSSB_FRAG_FORECAST_OK,
|
||||
|
||||
RSSB_CNVG_ONCE_QUERY_SEND,
|
||||
RSSB_CNVG_TWICE_QUERY_SEND,
|
||||
RSSB_CNVG_ONCE_QUERY_RECV,
|
||||
RSSB_CNVG_TWICE_QUERY_RECV,
|
||||
RSSB_INDEX_ONCE_QUERY_SEND,
|
||||
RSSB_INDEX_TWICE_QUERY_SEND,
|
||||
RSSB_INDEX_ONCE_QUERY_RECV,
|
||||
RSSB_INDEX_TWICE_QUERY_RECV,
|
||||
|
||||
RSSB_AV_ONCE_QUERY_SEND,
|
||||
RSSB_AV_TWICE_QUERY_SEND,
|
||||
RSSB_AV_ONCE_QUERY_RECV,
|
||||
RSSB_AV_TWICE_QUERY_RECV,
|
||||
|
||||
RSSB_SIP_ACK_KEY1,
|
||||
RSSB_SIP_ACK_KEY2,
|
||||
RSSB_SIP_ACK_KEY3,
|
||||
|
||||
RSSB_LOG_TYPE_MAXNUM,
|
||||
}RSSB_LOG_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSSB_RECV_OTHER_MEDIA, //not HLS and osmf
|
||||
RSSB_RECV_HLS_MEDIA,
|
||||
RSSB_HLS_TO_OTHER, //<2F><>HLS<4C><53>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
|
||||
RSSB_RECV_OSMF_MEDIA,
|
||||
RSSB_OSMF_TO_OTHER, //<2F><>OSMF<4D><46>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
|
||||
RSSB_RECV_FRAG_MEDIA,
|
||||
RSSB_FRAG_TO_OTHER, //<2F><><EFBFBD><EFBFBD>HLS OSMF<4D><46><EFBFBD><EFBFBD>Ƭ
|
||||
|
||||
RSSB_DATALOG_TYPE_MAXNUM,
|
||||
}RSSB_DATALOG_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSSB_CNVG_QUEUE,
|
||||
RSSB_INDEX_QUEUE,
|
||||
RSSB_WAIT_QUEUE,
|
||||
|
||||
RSSB_CNVG_HASH,
|
||||
|
||||
RSSB_SYSLOG_TYPE_MAXNUM,
|
||||
}RSSB_SYSLOG_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TOTAL_PKTS=0,
|
||||
TOTAL_BYTES,
|
||||
PPS,
|
||||
BPS,
|
||||
|
||||
|
||||
FAIL_PKTS,
|
||||
FAIL_BYTES,
|
||||
FAIL_PPS,
|
||||
FAIL_BPS,
|
||||
|
||||
LOG_STAT_MAXNUM,
|
||||
}LOG_STAT;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NUM_CUR=0,
|
||||
NUM_IN,
|
||||
NUM_OUT,
|
||||
|
||||
SYSLOG_STAT_MAXNUM,
|
||||
}SYSLOG_STAT;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
QUEUE_CURRENT=0,
|
||||
QUEUE_IN,
|
||||
QUEUE_OUT,
|
||||
|
||||
QUEUELOG_STAT_MAXNUM,
|
||||
}QUEUELOG_STAT;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HASH_CURRENT=0,
|
||||
HASH_NUM_EXPIRE,
|
||||
HASH_TIME_EXPIRE,
|
||||
|
||||
HASHLOG_STAT_MAXNUM,
|
||||
}HASHLOG_STAT;
|
||||
|
||||
void* thread_frag_rssb_sysinfo_output(void *param);
|
||||
void* thread_frag_rssb_stat_output(void *param);
|
||||
|
||||
void* thread_sysinfo_output(void *param);
|
||||
void* thread_stat_output(void *param);
|
||||
|
||||
|
||||
#endif
|
||||
1304
src/main.c
Normal file
1304
src/main.c
Normal file
File diff suppressed because it is too large
Load Diff
289
src/main.h
Normal file
289
src/main.h
Normal file
@@ -0,0 +1,289 @@
|
||||
#ifndef _MAIN_H
|
||||
#define _MAIN_H
|
||||
|
||||
#include <sys/un.h>
|
||||
#include </usr/include/stdint.h>
|
||||
|
||||
#define APP_FUNC 0 //<2F>ֻ<EFBFBD>APP
|
||||
#define VOIP_FUNC 0 //VOIP <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB>
|
||||
#define PIC_FUNC 0 //PIC <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB>
|
||||
|
||||
#include "MESA_list_queue.h"
|
||||
#include "MESA_htable.h"
|
||||
#include "MESA_trace.h"
|
||||
#include "MESA_timer.h"
|
||||
#include "usm_api.h"
|
||||
#include "Maat_rule.h"
|
||||
#include "KafkaProducer.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "AV_interface.h"
|
||||
#include "wiredLB.h"
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֵ<EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define CPZ_AV_PIC 0
|
||||
#define CPZ_VOIP 1
|
||||
|
||||
#define MAX_THREAD_NUM 32
|
||||
|
||||
/*sned data; send wins; send whitelist*/
|
||||
#define DEST_MAXNUM 8
|
||||
/*special media to windows*/
|
||||
#define SPECIAL_MEDIA_TYPE_MAXNUM 16 //in main.conf
|
||||
#define SPECIAL_MEDIA_TABLE_MAXNUM 256 //special media type is 0Xxx, less than 256
|
||||
|
||||
/*<2A><>Ŀȷ<C4BF>ϻ<EFBFBD><CFBB><EFBFBD><EFBFBD><EFBFBD>С*/
|
||||
#define ACK_BUF_SIZE 1500
|
||||
|
||||
typedef struct frag_rssb_parameter_s
|
||||
{
|
||||
void* asmis_log_handle;
|
||||
/*data msg rec*/
|
||||
void* recv_bizman[MAX_THREAD_NUM];
|
||||
void* answer_sapp_bizman; //send msg to sapp
|
||||
void* cpz_send_bizman; //send data to other cpz when multi
|
||||
void* appdtc_handle; //send msg to sapp
|
||||
|
||||
Maat_feather_t feather;
|
||||
|
||||
USM_t* a_usm_handle;
|
||||
unsigned int reader_cnt;
|
||||
int usm_on_flag;
|
||||
|
||||
MESA_lqueue_head* recv_bizman_lq; //bizman recv frag queue, queue num=thread_num
|
||||
MESA_lqueue_head* monitor_file_lq; //monitor service dump file
|
||||
MESA_lqueue_head* av_record_lq; //av record file
|
||||
MESA_lqueue_head* av_digest_record_lq; //av fuzzy_record file
|
||||
MESA_lqueue_head app_lq; //app queue
|
||||
|
||||
MESA_htable_handle media_monitor_hash; //media_monitor_hash because full_file monitoe
|
||||
MESA_htable_handle dumpfile_hash; //monitor dumpfile hash handle
|
||||
MESA_htable_handle media_hash; //media_hash
|
||||
|
||||
MESA_timer_t* index_query_timer[MAX_THREAD_NUM];
|
||||
|
||||
/*<2A><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5>*/
|
||||
void* dedup_hd; //av_dedup_handle
|
||||
void* dedup_logger; //av_dedup log
|
||||
MESA_timer_t* multisrc_timer[MAX_THREAD_NUM];
|
||||
|
||||
KafkaProducer* kafka_producer; //kafka
|
||||
|
||||
/*log*/
|
||||
FILE* media_create_file; //media create log
|
||||
FILE* media_expire_file; //media expire log
|
||||
FILE* resp_file; //survey log
|
||||
|
||||
pthread_mutex_t media_create_file_lock;
|
||||
pthread_mutex_t media_expire_file_lock;
|
||||
pthread_mutex_t resp_file_lock;
|
||||
|
||||
struct tm media_create_filetime;
|
||||
struct tm media_expire_filetime;
|
||||
struct tm resp_filetime;
|
||||
time_t cur_time;
|
||||
void* logger;
|
||||
void* mid_trace_hd; //pid trace log handle
|
||||
void* frag_logger; //about frag
|
||||
void* voip_logger; //about dedup
|
||||
|
||||
/*send data*/
|
||||
int send_fd[MAX_THREAD_NUM]; //unix socket : send frag
|
||||
int send_sd[MAX_THREAD_NUM]; //udp socket :
|
||||
|
||||
/*special media type*/
|
||||
char special_media_table[SPECIAL_MEDIA_TABLE_MAXNUM];
|
||||
|
||||
/*send data to windows system*/
|
||||
int send_windows_sd[MAX_THREAD_NUM]; //udp socket : special media send to windows system
|
||||
/*resp msg*/
|
||||
int recv_msg_fd; //unix socket : response msg recv
|
||||
int recv_msg_sd; //udp socket : response msg recv
|
||||
int send_msg_sd; //udp socket : response msg send , send whitelist
|
||||
|
||||
int frag_loglevel; //because cal IP,
|
||||
|
||||
/*feedback to qd*/
|
||||
msg_data_ack_t* fb_ack_hdr[MAX_THREAD_NUM];
|
||||
char fb_ack_buf[MAX_THREAD_NUM][ACK_BUF_SIZE];
|
||||
|
||||
/*av record*/
|
||||
FILE* av_record_curfile[MAX_THREAD_NUM];
|
||||
uint64_t av_record_curcnt[MAX_THREAD_NUM];
|
||||
|
||||
/*av fuzzy record*/
|
||||
FILE* av_digest_record_curfile[MAX_THREAD_NUM];
|
||||
uint64_t av_digest_record_curcnt[MAX_THREAD_NUM];
|
||||
|
||||
short expr_tableid;
|
||||
}frag_rssb_parameter_t;
|
||||
|
||||
typedef struct frag_rssb_configure_s
|
||||
{
|
||||
char store_filepath[MAX_PATH_LEN];
|
||||
char trace_filepath[MAX_PATH_LEN];
|
||||
char save_media_path[MAX_PATH_LEN];
|
||||
char media_create_filename[MAX_PATH_LEN]; //create media
|
||||
char media_expire_filename[MAX_PATH_LEN]; //expire media
|
||||
char resp_filename[MAX_PATH_LEN]; //about resp msg and monitor and block
|
||||
|
||||
/*media hash*/
|
||||
uint32_t media_hash_size;
|
||||
uint32_t media_hash_max_elem_num;
|
||||
uint32_t media_hash_expire_time;
|
||||
/*deduptd hash*/
|
||||
uint32_t deduptd_hash_size;
|
||||
uint32_t deduptd_hash_max_elem_num;
|
||||
uint32_t deduptd_hash_expire_time;
|
||||
|
||||
/*dumpfile hash*/
|
||||
uint32_t dumpfile_hash_size;
|
||||
uint32_t dumpfile_hash_max_elem_num;
|
||||
uint32_t dumpfile_hash_expire_time;
|
||||
/*monitor hash*/
|
||||
uint32_t monitor_hash_size;
|
||||
uint32_t monitor_hash_max_elem_num;
|
||||
uint32_t monitor_hash_expire_time;
|
||||
|
||||
/*monitor service : save file*/
|
||||
char monitor_file_root_dir[MAX_PATH_LEN];
|
||||
uint16_t monitor_file_switch;
|
||||
uint16_t monitor_file_days;
|
||||
int16_t fuzzy_digest_switch;
|
||||
int16_t modify_capIP_switch;
|
||||
|
||||
uint16_t bizman_port; //recv_bizman port, recv frag from sapp
|
||||
uint16_t bizman_ack_port; //answer_sapp_bizman port, send msg to sapp
|
||||
uint16_t msg_port;
|
||||
uint16_t store_filepath_switch;
|
||||
|
||||
uint16_t renew_time_min;
|
||||
uint16_t renew_time_max;
|
||||
uint16_t renew_time_step;
|
||||
/*send_msg_windows_sd , special media to windocs system*/
|
||||
uint16_t special_media_fwd_switch; // is deputy system data like MP4 send to remote windows system
|
||||
uint32_t special_media_wins_ip_num;
|
||||
uint32_t special_media_wins_port_num;
|
||||
in_addr_t special_media_wins_ip[DEST_MAXNUM];
|
||||
in_port_t special_media_wins_port[DEST_MAXNUM];
|
||||
|
||||
/*send_msg_sd*/
|
||||
struct sockaddr_in whitelist_addr[DEST_MAXNUM];
|
||||
uint32_t whitelist_addr_num;
|
||||
|
||||
/*send data by unix*/
|
||||
uint32_t send_dest_addr_num; //unix socket : send frag to dest
|
||||
struct sockaddr_un send_dest_addr[DEST_MAXNUM]; //unix socket : send frag to dest
|
||||
|
||||
/*send data by udp*/
|
||||
uint16_t send_dest_udp_port[DEST_MAXNUM]; //udp socket : send frag to dest
|
||||
uint32_t send_dest_udp_ip_num;
|
||||
in_addr_t send_dest_udp_iplist[DEST_MAXNUM]; //udp socket : send frag to dest
|
||||
|
||||
/*avrecord*/
|
||||
char avrecord_filepath[MAX_PATH_LEN];
|
||||
uint32_t avrecord_maxnum;
|
||||
uint32_t local_ip_nr;
|
||||
|
||||
uint32_t thread_num;
|
||||
uint16_t bizman_queue_mode; //0:<3A><EFBFBD><DEB6>н<EFBFBD><D0BD><EFBFBD> 1:<3A><><EFBFBD>л<EFBFBD><D0BB><EFBFBD>
|
||||
uint16_t avrecord_switch;
|
||||
uint16_t forecast_switch;
|
||||
uint32_t bizman_queue_maxnum; //bizman <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
/*<2A><><EFBFBD>ض<EFBFBD>Դҵ<D4B4><D2B5>*/
|
||||
uint32_t td_data_maxsize;
|
||||
int16_t av_dedup_switch;
|
||||
uint32_t multisrc_wait_timeout;
|
||||
uint32_t index_query_timeout;
|
||||
int16_t multisrc_timer_cb_maxtime;
|
||||
int16_t index_query_timer_cb_maxtime;
|
||||
int16_t dedup_invalid; //0:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1:<3A>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ϱ<EFBFBD> 2:
|
||||
/*debug*/
|
||||
int16_t all_hit_monitor_switch;
|
||||
int16_t all_hit_monitor_complete_rate;
|
||||
int16_t all_hit_filename; //<2F><><EFBFBD><EFBFBD>meidia_type<70><65><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
int16_t hls_in_aboffset_mode;
|
||||
int16_t json_local_switch;
|
||||
int16_t frag_survey_invalid;
|
||||
int16_t ack_switch;
|
||||
/*APPҵ<50><D2B5>*/
|
||||
int16_t app_switch;
|
||||
|
||||
int16_t IVI_switch;
|
||||
int16_t asmis_switch;
|
||||
int16_t cpz_type;
|
||||
|
||||
uint32_t* voip_survey_log_iplist; /*VOIP<49>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>IP*/
|
||||
uint16_t voip_survey_log_port;
|
||||
uint16_t voip_survey_log_ipnum;
|
||||
uint16_t voip_full_log_port;
|
||||
uint16_t voip_full_log_ipnum;
|
||||
uint32_t* voip_full_log_iplist; /*VOIP<49><50>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>IP*/
|
||||
|
||||
int16_t voip_filter_switch; /*VOIP<49><50><EFBFBD><EFBFBD>media_type<70><65><EFBFBD>й<EFBFBD><D0B9><EFBFBD>*/
|
||||
|
||||
char kafka_brokers[512];
|
||||
int16_t media_json_switch;
|
||||
uint32_t fwd_ip_nr;
|
||||
//WLB
|
||||
char wlb_topic[WLB_MAX_TAG_SIZE];
|
||||
char wlb_group_name[WLB_MAX_TAG_SIZE];
|
||||
char user_tag[WLB_MAX_TAG_SIZE];
|
||||
WLB_handle_t rssb_wlb_handle;
|
||||
uint16_t wlb_on;
|
||||
uint16_t health_check_interval;
|
||||
uint16_t data_port;
|
||||
uint32_t capacity;
|
||||
uint32_t cost;
|
||||
uint32_t wlb_report_interval;
|
||||
uint32_t enable_override;
|
||||
uint32_t health_check_port;
|
||||
int16_t save_media;
|
||||
|
||||
uint32_t hard_balance_port;
|
||||
}frag_rssb_configure_t;
|
||||
|
||||
typedef struct frag_rssb_status_s
|
||||
{
|
||||
void* fs_handle;
|
||||
void* sysfs_handle;
|
||||
uint32_t stat_interval;
|
||||
uint32_t sysinfo_interval;
|
||||
|
||||
uint64_t stat_info[LOG_TYPE_MAXNUM][LOG_STAT_MAXNUM];
|
||||
uint64_t send_stat[DEST_MAXNUM][LOG_STAT_MAXNUM];
|
||||
uint64_t send_lq_stat[DEST_MAXNUM][LOG_STAT_MAXNUM];//add by dumeijie
|
||||
uint64_t wins_send_stat[DEST_MAXNUM][LOG_STAT_MAXNUM];
|
||||
uint64_t whitelist_send_stat[DEST_MAXNUM][LOG_STAT_MAXNUM];
|
||||
uint64_t media_stat[MEDIALOG_TYPE_MAXNUM];
|
||||
uint64_t sysinfo_stat[SYSLOG_TYPE_MAXNUM][SYSLOG_STAT_MAXNUM];
|
||||
|
||||
/*stat*/
|
||||
int log_column_id[LOG_STAT_MAXNUM];
|
||||
int log_line_id[LOG_TYPE_MAXNUM];
|
||||
int sendlog_line_id[DEST_MAXNUM*2];
|
||||
int wins_sendlog_line_id[DEST_MAXNUM];
|
||||
int whitelist_sendlog_line_id[DEST_MAXNUM];
|
||||
int log_field_id[MEDIALOG_TYPE_MAXNUM]; //media_stat
|
||||
/*sysinfo*/
|
||||
int syslog_column_id[SYSLOG_STAT_MAXNUM];
|
||||
int syslog_line_id[SYSLOG_TYPE_MAXNUM];
|
||||
|
||||
/*field_stat*/
|
||||
char fs_app[32];
|
||||
char fs_ip[32];
|
||||
uint16_t fs_port;
|
||||
uint16_t fs_remote_switch;
|
||||
}frag_rssb_status_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1146
src/message.c
Normal file
1146
src/message.c
Normal file
File diff suppressed because it is too large
Load Diff
35
src/message.h
Normal file
35
src/message.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _MESSAGE_H
|
||||
#define _MESSAGE_H
|
||||
|
||||
#include <sys/un.h>
|
||||
#include </usr/include/stdint.h>
|
||||
|
||||
/*just for hash callback in proc_resp_checkresult */
|
||||
typedef struct temp_buf_s
|
||||
{
|
||||
char* buf;
|
||||
uint32_t size;
|
||||
}temp_buf_t;
|
||||
|
||||
|
||||
typedef struct monitor_hash_node_s
|
||||
{
|
||||
uint64_t porg_id;
|
||||
int hit_service;
|
||||
}monitor_hash_node_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void* recv_response_msg(void *param);
|
||||
void free_monitor_hash_node(void* data);
|
||||
int expire_monitor_hash_node(void *data, int eliminate_type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
565
src/service.c
Normal file
565
src/service.c
Normal file
@@ -0,0 +1,565 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
#include "service.h"
|
||||
#include "common.h"
|
||||
#include "bizman.h"
|
||||
#include "my_socket.h"
|
||||
#include "AV_interface.h"
|
||||
#include "AV_sendback_in.h"
|
||||
#include "frag_reassembly_in.h"
|
||||
#include "log.h"
|
||||
#include "frag_proc.h"
|
||||
#include "frag_voip.h"
|
||||
|
||||
extern frag_rssb_parameter_t g_frag_run;
|
||||
extern frag_rssb_configure_t g_frag_cfg;
|
||||
extern frag_rssb_status_t g_frag_stat;
|
||||
extern frag_reassembly_t frag_rssb; //use media hash
|
||||
extern const char* hash_eliminate_type[3];
|
||||
|
||||
media_type_t g_av_mediatype_des[MEDIATYPE_MAXNUM] =
|
||||
{
|
||||
{FILE_UNKNOWN, "unkonwn"},
|
||||
{FILE_VIDEO, "video"},
|
||||
{FILE_WMV, "wmv"},
|
||||
{FILE_MPG, "mpg"},
|
||||
{FILE_FLV, "flv"},
|
||||
{FILE_RMFF, "rmff"},
|
||||
{FILE_AVI, "avi"},
|
||||
{FILE_SWF, "swf"},
|
||||
{FILE_MPG4, "mpg4"},
|
||||
{FILE_AIFF, "aiff"},
|
||||
{FILE_OGG, "ogg"},
|
||||
{FILE_DRC, "drc"},
|
||||
{FILE_DIRECTSHOW, "directshow"},
|
||||
{FILE_FLIC, "flic"},
|
||||
{FILE_INDEO, "indeo"},
|
||||
{FILE_MKV, "mkv"},
|
||||
{FILE_AUDIO, "audio"},
|
||||
{FILE_MP3, "mp3"},
|
||||
{MMS_TYPE, "mms"},
|
||||
{RTSP_RDT_TYPE, "rtsp_rdt"},
|
||||
{RTSP_RTP_TYPE, "rtsp_rtp"},
|
||||
{FILE_HLS, "ts"},
|
||||
{FILE_OSMF, "osmf"},
|
||||
{FILE_IMAGE, "image"},
|
||||
{FILE_JPG, "jpg"},
|
||||
{FILE_BMP, "omp"},
|
||||
{FILE_GIF, "gif"},
|
||||
};
|
||||
|
||||
media_type_t g_voip_mediatype_des[VOIP_MEDIATYPE_MAXNUM] =
|
||||
{
|
||||
{AUDIO_UNKNOWN,"unkonwn"},
|
||||
{AUDIO_G711_ULAW,"G711_U"},
|
||||
{AUDIO_G711_ALAW,"G711_A"},
|
||||
{AUDIO_G722,"G722"},
|
||||
{AUDIO_G723,"G723"},
|
||||
{AUDIO_G726_40,"G726_40"},
|
||||
{AUDIO_G726_32,"G726_32"},
|
||||
{AUDIO_G726_24,"G726_24"},
|
||||
{AUDIO_G726_16,"G726_16"},
|
||||
{AUDIO_AAL2_G726_40,"G726_40"},
|
||||
{AUDIO_AAL2_G726_32,"G726_32"},
|
||||
{AUDIO_AAL2_G726_24,"G726_24"},
|
||||
{AUDIO_AAL2_G726_16,"G726_16"},
|
||||
{AUDIO_G728,"G728"},
|
||||
{AUDIO_G729D,"G729D"},
|
||||
{AUDIO_G729E,"G729E"},
|
||||
{AUDIO_GSM,"GSM"},
|
||||
{AUDIO_GSM_EFR,"GSM_EFR"},
|
||||
{AUDIO_ILBC,"ILBC"},
|
||||
{AUDIO_AMR,"AMR"},
|
||||
{AUDIO_AMR_WB,"AMR_WB"},
|
||||
{AUDIO_SILK,"SILK"},
|
||||
{AUDIO_LPC,"LPC"},
|
||||
{AUDIO_LPC1016,"LPC1016"},
|
||||
{AUDIO_LPC1015,"LPC1015"},
|
||||
{AUDIO_L16,"L16"},
|
||||
{AUDIO_SPEEX,"SPEEX"},
|
||||
{AUDIO_L8,"L8"},
|
||||
{AUDIO_MPA,"MPA"},
|
||||
{AUDIO_DVI4,"DVI4"},
|
||||
{AUDIO_VDVI,"VDVI"},
|
||||
{AUDIO_CN,"CN"},
|
||||
{AUDIO_RED,"RED"},
|
||||
{AUDIO_QCELP,"QCELP"},
|
||||
{AUDIO_EVRC0,"EVRC0"},
|
||||
{AUDIO_EVRCB0,"EVRCB0"},
|
||||
{AUDIO_G729,"G729"},
|
||||
{AUDIO_VIVOX,"VIVOX"}
|
||||
};
|
||||
|
||||
/***************************************dumpfile service***************************************************/
|
||||
int free_file_frag(file_frag_t *data)
|
||||
{
|
||||
file_frag_t* file_frag = (file_frag_t*)data;
|
||||
if(NULL!=file_frag)
|
||||
{
|
||||
if(file_frag->data!=NULL)
|
||||
{
|
||||
free(file_frag->data);
|
||||
}
|
||||
free(file_frag);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gen_monitor_file_dir(time_t create_time, uint64_t prog_id, char *path, int len)
|
||||
{
|
||||
if(NULL == path || len < 256 || 0 == prog_id)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
char today[64] = {0};
|
||||
static const char* hex = "0123456789ABCDEF";
|
||||
uint16_t* p16 = NULL;
|
||||
char* p = NULL;
|
||||
int i = 0;
|
||||
int step = 0;
|
||||
int write_len = 0;
|
||||
struct tm a_tm;
|
||||
|
||||
localtime_r(&create_time,&a_tm);
|
||||
memset(today, 0, sizeof(today) );
|
||||
strftime(today, sizeof(today), "%Y%m%d", &a_tm);
|
||||
|
||||
p = path;
|
||||
if(g_frag_cfg.monitor_file_root_dir[strlen(g_frag_cfg.monitor_file_root_dir)-1]=='/')
|
||||
{
|
||||
g_frag_cfg.monitor_file_root_dir[strlen(g_frag_cfg.monitor_file_root_dir)-1]='\0';
|
||||
}
|
||||
if(g_frag_cfg.monitor_file_days)
|
||||
{
|
||||
write_len= snprintf(p,len, "%s/%s", g_frag_cfg.monitor_file_root_dir,today);
|
||||
if(write_len==len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
p += write_len;
|
||||
}
|
||||
p16 = (uint16_t*)&prog_id;
|
||||
for(i = 0; i < 5; i += 1)
|
||||
{
|
||||
*p++ = '/';
|
||||
if(i % 2 == 1)
|
||||
{
|
||||
*p++ = hex[(0xf000 & *p16) >> 12];
|
||||
step = 2;
|
||||
}
|
||||
*p++ = hex[(0x0f00 & *p16) >> 8];
|
||||
*p++ = hex[(0x00f0 & *p16) >> 4];
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
*p++ = hex[(0x000f & *p16)];
|
||||
step = 1;
|
||||
}
|
||||
*p = '\0';
|
||||
p16 = (uint16_t*)( (uint8_t*)p16 + step);
|
||||
}
|
||||
return p-path;
|
||||
}
|
||||
|
||||
int gen_monitor_file_path(time_t create_time, uint64_t prog_id, char *file_suffix, char *path, int len)
|
||||
{
|
||||
int offset=0;
|
||||
int write_len=0;
|
||||
if(NULL == path || len < 256 || 0 == prog_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
offset = gen_monitor_file_dir(create_time, prog_id, path, len);
|
||||
write_len = snprintf(path+offset,len-offset, "/%" PRIu64 ".%s", prog_id, file_suffix);
|
||||
if(write_len==len-offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
offset += write_len;
|
||||
offset++;
|
||||
return offset;
|
||||
}
|
||||
|
||||
void free_dumpfile_hash_node(void* data)
|
||||
{
|
||||
dumpfile_hash_node_t* dump_hnode = (dumpfile_hash_node_t*)data;
|
||||
if(NULL!=dump_hnode)
|
||||
{
|
||||
if(NULL!=dump_hnode->fp)
|
||||
{
|
||||
fclose(dump_hnode->fp);
|
||||
}
|
||||
free(dump_hnode);
|
||||
dump_hnode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int expire_dumpfile_hash_node(void *data, int eliminate_type)
|
||||
{
|
||||
dumpfile_hash_node_t* dump_hnode = (dumpfile_hash_node_t*)data;
|
||||
switch(eliminate_type)
|
||||
{
|
||||
case ELIMINATE_TYPE_NUM:
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[DUMPFILE_HASH][HASH_NUM_EXPIRE]);
|
||||
break;
|
||||
case ELIMINATE_TYPE_TIME:
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[DUMPFILE_HASH][HASH_TIME_EXPIRE]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} expire_dumpfile_hash_node %s: [filemane: %s]",
|
||||
__FILE__,__LINE__,
|
||||
hash_eliminate_type[eliminate_type],
|
||||
dump_hnode->filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* gen_filesuffix_by_mediatype(char *file_suffix, uint8_t mediatype, uint8_t proto)
|
||||
{
|
||||
if(g_frag_cfg.cpz_type == CPZ_VOIP)
|
||||
{
|
||||
for(int i=1;i<MEDIATYPE_MAXNUM;i++)
|
||||
{
|
||||
if(mediatype==g_voip_mediatype_des[i].media_type)
|
||||
{
|
||||
return g_voip_mediatype_des[i].media_type_desc;
|
||||
}
|
||||
}
|
||||
return g_voip_mediatype_des[0].media_type_desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(proto==AV_PROTOCOL_RTMP)
|
||||
{
|
||||
return (char*)"rtmp";
|
||||
}
|
||||
for(int i=1;i<MEDIATYPE_MAXNUM;i++)
|
||||
{
|
||||
if(mediatype==g_av_mediatype_des[i].media_type)
|
||||
{
|
||||
return g_av_mediatype_des[i].media_type_desc;
|
||||
}
|
||||
}
|
||||
return g_av_mediatype_des[0].media_type_desc;
|
||||
}
|
||||
}
|
||||
|
||||
long dumpfile_hash_search_cb(void *data, const uint8_t *key, uint size, void *user_arg)
|
||||
{
|
||||
file_frag_t* file_frag = (file_frag_t*)user_arg;
|
||||
char* filename = file_frag->key.filename;
|
||||
FILE* fp = NULL;
|
||||
int rec = 0;
|
||||
dumpfile_hash_node_t* dump_hnode = (dumpfile_hash_node_t*)data;
|
||||
|
||||
if(NULL==dump_hnode)
|
||||
{
|
||||
rec = mkdir_r(filename);
|
||||
if(rec>=0)
|
||||
{
|
||||
fp = fopen(filename,"r+");
|
||||
if(NULL==fp)
|
||||
{
|
||||
fp = fopen(filename,"w");
|
||||
if(NULL!=fp)
|
||||
{
|
||||
fclose(fp);
|
||||
}
|
||||
fp = fopen(filename,"r+");
|
||||
}
|
||||
if(NULL!=fp)
|
||||
{
|
||||
dump_hnode = (dumpfile_hash_node_t*)calloc(1, sizeof(dumpfile_hash_node_t));
|
||||
dump_hnode->fp = fp;
|
||||
memcpy(dump_hnode->filename, filename, strlen(filename));
|
||||
rec = MESA_htable_add(g_frag_run.dumpfile_hash, key, size,(const void*)dump_hnode);
|
||||
if(0>rec)
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} dumpfile_hash MESA_htable_add error: [filename: %s]",
|
||||
__FILE__,__LINE__, filename);
|
||||
free_dumpfile_hash_node(dump_hnode);
|
||||
dump_hnode = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} dumpfile gen_monitor_file_path error: [filename:%s, mid: %llu]",
|
||||
__FILE__,__LINE__, filename, file_frag->key.mid);
|
||||
}
|
||||
}
|
||||
|
||||
if(NULL!=dump_hnode && NULL!=dump_hnode->fp)
|
||||
{
|
||||
file_frag->key.fp = dump_hnode->fp;
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_INFO, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} DUMP FILE [filename:%s, MID:%llu, offset_in:%llu, datalen:%u]",
|
||||
__FILE__,__LINE__,filename, file_frag->key.mid, file_frag->offset_in, file_frag->datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(g_frag_run.logger, RLOG_LV_FATAL, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} dumpfile open monitor_file_path error, maybe fd is full: [filename:%s, mid: %llu]",
|
||||
__FILE__,__LINE__, filename, file_frag->key.mid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------monitor_service_dump_file_thread---------------*/
|
||||
void* monitor_service_dump_file_thread(void *param)
|
||||
{
|
||||
file_frag_t* file_frag = NULL;
|
||||
long file_frag_len = sizeof(file_frag);
|
||||
long rec_cb = 0;
|
||||
long tid = (long)param;
|
||||
|
||||
while(1)
|
||||
{
|
||||
file_frag = NULL;
|
||||
MESA_lqueue_read_head(g_frag_run.monitor_file_lq[tid], &file_frag, &file_frag_len);
|
||||
|
||||
MESA_htable_search_cb(g_frag_run.dumpfile_hash, (const uint8_t*)&file_frag->key.mid, sizeof(file_frag->key.mid),
|
||||
dumpfile_hash_search_cb, file_frag, &rec_cb);
|
||||
if(NULL!=file_frag->key.fp)
|
||||
{
|
||||
fseek(file_frag->key.fp, file_frag->offset_in, SEEK_SET);
|
||||
fwrite(file_frag->data, file_frag->datalen, 1, file_frag->key.fp);
|
||||
//fflush(file_frag->key.fp);
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[DUMPFILE_QUEUE][QUEUE_OUT]);
|
||||
atomic_inc(&g_frag_stat.stat_info[MONITOR_DUMP_FILE][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[MONITOR_DUMP_FILE][TOTAL_BYTES], file_frag->datalen);
|
||||
MESA_lqueue_get_head(g_frag_run.monitor_file_lq[tid], &file_frag, &file_frag_len);
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_DEBUG, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} DUMP FILE from queue [MID:%llu, offset_in:%llu, datalen:%u]",
|
||||
__FILE__,__LINE__,file_frag->key.mid, file_frag->offset_in, file_frag->datalen);
|
||||
free_file_frag(file_frag);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*file full, sleep to wait expire*/
|
||||
sleep(g_frag_cfg.dumpfile_hash_expire_time/2);
|
||||
}
|
||||
file_frag = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void monitor_service_dump_file(frag_in_t* frg, media_t* mdi)
|
||||
{
|
||||
if(mdi->monitor_path==NULL) return;
|
||||
file_frag_t* file_frag = (file_frag_t*)calloc(1, sizeof(file_frag_t));
|
||||
|
||||
if(g_frag_cfg.cpz_type==CPZ_VOIP)
|
||||
{
|
||||
/*SIP<49><50><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>8<EFBFBD><38><EFBFBD>ֽڵ<D6BD>time+SEQ,<2C><>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>*/
|
||||
file_frag->data = (char*)malloc(frg->datalen-VOIP_DATA_TIME_SEQ_LEN);
|
||||
file_frag->datalen = frg->datalen-VOIP_DATA_TIME_SEQ_LEN;
|
||||
memcpy(file_frag->data, frg->data+VOIP_DATA_TIME_SEQ_LEN, file_frag->datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
file_frag->data = (char*)malloc(frg->datalen);
|
||||
file_frag->datalen = frg->datalen;
|
||||
memcpy(file_frag->data, frg->data, file_frag->datalen);
|
||||
}
|
||||
file_frag->offset_in = frg->offset;
|
||||
file_frag->key.mid = frg->mid;
|
||||
//file_frag->key.proto = mdi->proto;
|
||||
//file_frag->key.media_type = mdi->media_type;
|
||||
//file_frag->key.create_time = mdi->create_time;
|
||||
memcpy(file_frag->key.filename, mdi->monitor_path, strlen(mdi->monitor_path));
|
||||
MESA_lqueue_join_tail(g_frag_run.monitor_file_lq[frg->thread_seq], &file_frag, sizeof(file_frag));
|
||||
atomic_inc(&g_frag_stat.sysinfo_stat[DUMPFILE_QUEUE][QUEUE_IN]);
|
||||
MESA_handle_runtime_log(g_frag_run.frag_logger, RLOG_LV_DEBUG, FRAG_REASSEMBLY_MODULE_NAME,
|
||||
"{%s:%d} DUMP FILE to queue [MID:%llu, offset_in:%llu, datalen:%u]",
|
||||
__FILE__,__LINE__,file_frag->key.mid, file_frag->offset_in, file_frag->datalen);
|
||||
}
|
||||
|
||||
/**************************************monitor service************************************/
|
||||
int create_monitor(char *buf, int bufsize, media_t* mdi, uint8_t cfg_id, uint8_t service)
|
||||
{
|
||||
char ip_str[64] = {0};
|
||||
int local_path_len = 0;
|
||||
int path_len = 0;
|
||||
msg_header_t* monitor_header = NULL;
|
||||
resp_checkresult_t* monitor_msg = NULL;
|
||||
char* file_suffix =NULL;
|
||||
|
||||
monitor_header = (msg_header_t*)buf;
|
||||
monitor_msg = (resp_checkresult_t*)((char*)monitor_header + MSG_HEADER_LEN);
|
||||
|
||||
monitor_header->magic_num = PROTO_MAGICNUM;
|
||||
monitor_header->version = PROTO_VERSION;
|
||||
monitor_header->msg_type = MSG_RESP_CHECKRESULT;
|
||||
monitor_header->cont_len = 0;
|
||||
|
||||
memcpy(monitor_msg->prog_id, &mdi->mid, sizeof(mdi->mid));
|
||||
monitor_msg->service = service;
|
||||
monitor_msg->level = 100; /* any number >0 is OK */
|
||||
monitor_msg->cfg_id = (uint32_t)cfg_id;
|
||||
|
||||
/*<2A>ļ<EFBFBD>·<EFBFBD><C2B7>*/
|
||||
if(mdi->monitor_path==NULL)
|
||||
{
|
||||
mdi->monitor_path = (char*)calloc(1, MAX_PATH_LEN);
|
||||
/*<2A><><EFBFBD><EFBFBD>media_type<70><65><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>*/
|
||||
if(g_frag_cfg.all_hit_filename)
|
||||
{
|
||||
file_suffix = gen_filesuffix_by_mediatype(file_suffix, mdi->media_type, mdi->proto);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mdi->proto==AV_PROTOCOL_HTTP_STREAM)
|
||||
{
|
||||
file_suffix = (char*)"jpeg";
|
||||
}
|
||||
else
|
||||
{
|
||||
file_suffix = (char*)"flv";
|
||||
}
|
||||
}
|
||||
local_path_len = gen_monitor_file_path(mdi->create_time, mdi->mid, file_suffix, mdi->monitor_path, 1460-MSG_HEADER_LEN-MSG_RESP_CHECKRESULT_LEN);
|
||||
if(local_path_len < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
inet_ntop(AF_INET, &g_frag_cfg.local_ip_nr, ip_str, sizeof(ip_str));
|
||||
path_len = snprintf((char*)monitor_msg + MSG_RESP_CHECKRESULT_LEN,
|
||||
1460-MSG_HEADER_LEN-MSG_RESP_CHECKRESULT_LEN,
|
||||
"%s:%s", ip_str, mdi->monitor_path);
|
||||
path_len++; //snprintf's return lenth not including '\0',add one.
|
||||
|
||||
monitor_header->cont_len = path_len + MSG_RESP_CHECKRESULT_LEN;
|
||||
return monitor_header->cont_len + MSG_HEADER_LEN;
|
||||
}
|
||||
|
||||
long search_monitor_hash_cb(void *data, const uint8_t *key, uint size, void *user_arg)
|
||||
{
|
||||
if(NULL!=data)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------audio_lang_monitor_service when create_media for every frag_unit ---------------*/
|
||||
void audio_lang_monitor_service(uint32_t src_ip, media_t* mdi)
|
||||
{
|
||||
long rec_cb = 0;
|
||||
char monitor_buf[MONITOR_BUFSIZE] = {0};
|
||||
int monitor_len = 0;
|
||||
char pbuf[32] = {0};
|
||||
int buf_len = 32;
|
||||
|
||||
MESA_htable_search_cb(g_frag_run.media_monitor_hash, (const unsigned char*)&mdi->mid, sizeof(mdi->mid), search_monitor_hash_cb, NULL, &rec_cb);
|
||||
if(rec_cb)
|
||||
{
|
||||
monitor_len = create_monitor(monitor_buf, MONITOR_BUFSIZE, mdi, 1 , SERVICE_AUDIO_LANG_FULL);
|
||||
FLAG_SET(mdi->flag, PROG_FLAG_DUMP);
|
||||
bizman_send(g_frag_run.answer_sapp_bizman,
|
||||
mdi->thread_seq,
|
||||
src_ip ,
|
||||
g_frag_cfg.msg_port,
|
||||
monitor_buf,
|
||||
monitor_len,
|
||||
1,BIZMAN_RELIABLE_SEND|BIZMAN_SMOOTH_DEST|BIZMAN_PUSH_SEND);
|
||||
|
||||
inet_ntop(AF_INET, &src_ip, pbuf, buf_len);
|
||||
resp_write_to_log(SEND_LANG_MONITOR, NULL, mdi, pbuf,0);
|
||||
atomic_inc(&g_frag_stat.stat_info[AUDIO_LANG_MONITOR_OUT][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[AUDIO_LANG_MONITOR_OUT][TOTAL_BYTES], monitor_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------config_monitor_service when create_media if frag_unit hit service 0x80 form sapp---------------*/
|
||||
void config_monitor_service(uint32_t src_ip, media_t* mdi)
|
||||
{
|
||||
char monitor_buf[MONITOR_BUFSIZE] = {0};
|
||||
int monitor_len = 0;
|
||||
char pbuf[32] = {0};
|
||||
int buf_len = 32;
|
||||
|
||||
/*<2A>ظ<EFBFBD><D8B8><EFBFBD>Դ֮ǰ<D6AE>Ľ<EFBFBD><C4BD>飬<EFBFBD><E9A3AC><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>Ŀ*/
|
||||
monitor_len = create_monitor(monitor_buf, MONITOR_BUFSIZE, mdi, 0, mdi->hit_service);
|
||||
|
||||
FLAG_SET(mdi->flag, PROG_FLAG_DUMP);
|
||||
bizman_send(g_frag_run.answer_sapp_bizman,
|
||||
mdi->thread_seq,
|
||||
src_ip,
|
||||
g_frag_cfg.msg_port,
|
||||
monitor_buf,
|
||||
monitor_len,
|
||||
1,BIZMAN_RELIABLE_SEND|BIZMAN_SMOOTH_DEST|BIZMAN_PUSH_SEND);
|
||||
|
||||
inet_ntop(AF_INET, &src_ip, pbuf, buf_len);
|
||||
resp_write_to_log(SEND_CONFIG_MONITOR, NULL, mdi, pbuf,0);
|
||||
atomic_inc(&g_frag_stat.stat_info[CONFIG_MONITOR_OUT][TOTAL_PKTS]);
|
||||
atomic_add(&g_frag_stat.stat_info[CONFIG_MONITOR_OUT][TOTAL_BYTES] , monitor_len);
|
||||
}
|
||||
|
||||
/******************************************************sendto wins system service****************************************************/
|
||||
int is_hit_media_detail_character(const unsigned char* buf,int buf_len)
|
||||
{
|
||||
int i=0,inuse_character_num=1;
|
||||
const unsigned char mp4_character[]={0x66,0x74,0x79,0x70};//mp4 from zhangdongming 20120903
|
||||
media_character_t accept_media_character[MAX_MEDIA_CHARACTER_NUM];
|
||||
accept_media_character[0].character=mp4_character;
|
||||
accept_media_character[0].start_offset=4;
|
||||
accept_media_character[0].len=sizeof(mp4_character);
|
||||
for(i=0;i<inuse_character_num;i++)
|
||||
{
|
||||
if(buf_len>=accept_media_character[i].len+accept_media_character[i].start_offset
|
||||
&&0==memcmp(buf+accept_media_character[i].start_offset,accept_media_character[i].character,accept_media_character[i].len))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------update_special_media_service when frag offset=0-----------------*/
|
||||
long update_special_media_service(media_t* mdi, frag_in_t* frg)
|
||||
{
|
||||
//deep judge media type to windows
|
||||
if(0==is_hit_media_detail_character((const unsigned char*)frg->data, frg->datalen))
|
||||
{
|
||||
FLAG_CLEAR(mdi->flag, PROG_FLAG_EXCP);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------set_special_media_service when create_media--------------------*/
|
||||
void set_special_media_service(uint16_t media_type, media_t* mdi)
|
||||
{
|
||||
if(g_frag_run.special_media_table[media_type])
|
||||
{
|
||||
FLAG_SET(mdi->flag, PROG_FLAG_EXCP);
|
||||
}
|
||||
}
|
||||
|
||||
78
src/service.h
Normal file
78
src/service.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef _SERVICE_H
|
||||
#define _SERVICE_H
|
||||
|
||||
#include "frag_reassembly_in.h"
|
||||
|
||||
#define MONITOR_BUFSIZE 1500 //monitor suvery buflen
|
||||
#define PROG_FLAG_EXCP 0x01 //data need send to windows deputy system
|
||||
#define PROG_FLAG_DUMP 0x02 //monitor hit data by frontier
|
||||
#define PROG_OFFSET_ZERO 0x04 //monitor hit data by frontier
|
||||
#define PROG_SEND_META 0x08 //monitor hit data by frontier
|
||||
|
||||
#define MAX_MEDIA_CHARACTER_NUM 32 //is_hit_media_detail_character
|
||||
|
||||
/*<2A><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#define ALL_HIT_MONITOR_SWITCH 1 //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC>⽨<EFBFBD>飬dump<6D>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define ALL_HIT_MONITOR_FULLFILE 2 //dumpfile <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴﵽһ<EFB5BD><D2BB><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
#define MEDIATYPE_MAXNUM 64
|
||||
#define VOIP_MEDIATYPE_MAXNUM 64
|
||||
|
||||
typedef struct file_id_s
|
||||
{
|
||||
uint64_t mid;
|
||||
//time_t create_time;
|
||||
//uint8_t media_type;
|
||||
//uint8_t proto;
|
||||
FILE* fp;
|
||||
char filename[MAX_PATH_LEN];
|
||||
} file_id_t;
|
||||
|
||||
typedef struct media_type_s
|
||||
{
|
||||
uint8_t media_type;
|
||||
char media_type_desc[32];
|
||||
} media_type_t;
|
||||
|
||||
typedef struct file_frag_s
|
||||
{
|
||||
file_id_t key;
|
||||
uint64_t offset_in;
|
||||
char* data;
|
||||
uint32_t datalen;
|
||||
}file_frag_t;
|
||||
|
||||
typedef struct _media_character
|
||||
{
|
||||
const unsigned char* character;
|
||||
int start_offset;
|
||||
int len;
|
||||
}media_character_t;
|
||||
|
||||
typedef struct dumpfile_hash_node_s
|
||||
{
|
||||
FILE* fp;
|
||||
char filename[MAX_PATH_LEN];
|
||||
}dumpfile_hash_node_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void monitor_service_dump_file(frag_in_t* frg, media_t* mdi);
|
||||
void* monitor_service_dump_file_thread(void *param);
|
||||
void config_monitor_service(uint32_t src_ip, media_t* mdi);
|
||||
void audio_lang_monitor_service(uint32_t src_ip, media_t* mdi);
|
||||
long update_special_media_service(media_t* mdi, frag_in_t* frg);
|
||||
void set_special_media_service(uint16_t media_type, media_t* mdi);
|
||||
void free_dumpfile_hash_node(void* data);
|
||||
int expire_dumpfile_hash_node(void *data, int eliminate_type);
|
||||
int gen_monitor_file_path(time_t create_time, uint64_t prog_id, char *file_suffix, char *path, int len);
|
||||
int gen_monitor_file_dir(time_t create_time, uint64_t prog_id, char *path, int len);
|
||||
char* gen_filesuffix_by_mediatype(char *file_suffix, uint8_t mediatype, uint8_t proto);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
49
src/support/Businessman/Makefile
Normal file
49
src/support/Businessman/Makefile
Normal file
@@ -0,0 +1,49 @@
|
||||
#################################################################################
|
||||
# Businessman Data Exchange System v0.1 #
|
||||
# Build by zhengchao@iie.ac.cn #
|
||||
# 2011-09-19 #
|
||||
#################################################################################
|
||||
CC = g++
|
||||
CFLAGS = -g -O2 -Wall -fPIC -fvisibility=hidden
|
||||
LDFLAGS = -lstdc++
|
||||
#CFLAGS +=-DBIZMAN_DEBUG
|
||||
CFLAGS +=-DBIZMAN_DEBUG_LIST
|
||||
CFLAGS +=-DDEPLOY_YSP_SYSTEM
|
||||
#CFLAGS +=-DBIZMAN_DEBUG_DETAILS
|
||||
LIBS = -lpthread -lz
|
||||
OBJECTS = hash.o list.o businessman_error.o businessman_time.o network_layer.o smooth_send.o\
|
||||
reliable_send.o reliable_recv.o stream_recover.o businessman_core.o businessman_packet.o
|
||||
TEST_OBJ = test.o
|
||||
TARGETLIB = libbusinessman.a
|
||||
TARGETSO = libbusinessman.so
|
||||
TARGETEXE = test_bizman
|
||||
.cpp.o:
|
||||
$(CC) -c -o $@ $(CFLAGS) $<
|
||||
|
||||
.PHONY: all clean
|
||||
all:$(TARGETLIB) $(TARGETSO)
|
||||
#$(TARGETEXE)
|
||||
cp $(TARGETLIB) ../../lib/
|
||||
$(TARGETLIB):$(OBJECTS)
|
||||
ar cqs $(TARGETLIB) $(OBJECTS)
|
||||
$(TARGETSO):$(OBJECTS)
|
||||
$(CC) -o $(TARGETSO) $(CFLAGS) $(OBJECTS) -shared
|
||||
$(TARGETEXE):$(TEST_OBJ) $(TARGETLIB)
|
||||
$(CC) -o $(TARGETEXE) $(CFLAGS) $(TEST_OBJ) $(TARGETLIB) $(LIBS)
|
||||
hash.o:hash.cpp hash.h
|
||||
list.o:list.cpp list.h
|
||||
businessman_error.o:businessman_error.cpp businessman_error.h
|
||||
businessman_time.o:businessman_time.cpp businessman_time.h businessman_limit.h
|
||||
businessman_packet.o:businessman_packet.cpp businessman_packet.h
|
||||
network_layer.o:network_layer.cpp network_layer.h
|
||||
smooth_send.o:smooth_send.cpp smooth_send.h businessman_limit.h businessman_packet.h businessman_lock.h
|
||||
reliable_send.o:reliable_send.cpp reliable_send.h businessman_limit.h businessman_packet.h
|
||||
reliable_recv.o:reliable_recv.cpp reliable_recv.h businessman_limit.h businessman_packet.h
|
||||
stream_recover.o:stream_recover.cpp stream_recover.h businessman_limit.h businessman_packet.h businessman_lock.h
|
||||
businessman_core.o:businessman_core.cpp businessman_core.h bizman.h businessman_packet.h smooth_send.h reliable_send.h\
|
||||
reliable_recv.h stream_recover.h
|
||||
test.o:test.cpp bizman.h
|
||||
clean:
|
||||
rm -f $(TARGETEXE) $(TARGETLIB) $(TARGETSO) $(OBJECTS) $(TEST_OBJ)
|
||||
|
||||
|
||||
161
src/support/Businessman/bizman.h
Normal file
161
src/support/Businessman/bizman.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*Businessman Data Exchange System
|
||||
*Based on the short story "The fisherman and the businessman"
|
||||
*Author:zhengchao@iie.ac.cn
|
||||
*History:2011-08-24 first build;
|
||||
2011-09-20 v0.01 start test;
|
||||
2011-12-31 v0.02 multi bug fixed;
|
||||
2012-01-16 memset 1MB memory can cause obvious performance reduction;
|
||||
2012-01-19 v0.03 1)support multi cast interface
|
||||
2)support smooth by dest ip and port;
|
||||
2012-03-06 v0.04 1)fix crash recovery bug;
|
||||
2)support chunk mode receive;
|
||||
3)support push send,send immediately after smooth without timeout;
|
||||
2012-03-08 v0.05 1)add choke recv mode,recv will blocked if no data in bizman;
|
||||
2012-03-12 v0.06 1)add magic number as packet header check;
|
||||
2)fix bug,when receiver crash restore leave gabarge in to_ack_timout_queue and
|
||||
ready_index_queue;
|
||||
2012-03-13 v0.07 1)count_last_frag_num_in_packet bug fixed;
|
||||
2)defrozen failed bug caused by no sendtimes reset fixed;
|
||||
3)fix memleaks at destory sender when receiver crush;
|
||||
2012-03-15 v0.07 1)fix copy_recv_data's queue operation before mutex;
|
||||
2)defrozen stream's first slice maybe incomplete is normal,because its previous part
|
||||
have been abandoned;
|
||||
2012-03-19 v0.08 1)add use pag(special network interface)send packets;
|
||||
2012-03-20 v0.09 1)reconstruct bizman.h,hide internal information to outside;
|
||||
2012-03-21 v0.10 1)use define instead of const in bizman.h
|
||||
2)rename functions in hash.cpp,to avoid function name collision in link
|
||||
2012-03-22 v0.11 1)add simple statistic,read reliable layer's stream first packet send and resend count;
|
||||
2012-03-26 v0.12 add reliable receive stream expire,fix stream expire bug in reliabe send;
|
||||
2012-03-29 v0.13 1)fix stream expire bug in reliable receive;
|
||||
2) improve send and resend statistic;
|
||||
2012-04-01 v0.14 1)fix bug when receive reduandent force establish stream packet reduandent, cause
|
||||
app receive duplicate app data.Add force establish stream interval to fix this bug;
|
||||
2)On heavy load,may expire send stream which have in use task, will screwed queue,
|
||||
fixed by check stream's in_use_task_num before expired;
|
||||
2012-04-11 v0.15 1)add sender cached packets limit;
|
||||
2)stat dropped pkts;
|
||||
3)fix bugs, send smooth stream expire time + max resend interval *2 = reliabe recv stream
|
||||
expire time,send smooth stream expire time > reliable send time;
|
||||
2012-04-12 v0.16 1)rebuild stat interface;
|
||||
2)fix bugs of memory corrupt caused by thread conflict when recv,enlarge mutex proctect
|
||||
range;
|
||||
2012-04-14 v0.18 1)fix do_actual_send's sendto return value judgemen;
|
||||
2)fix add_raw_packet function false abandon dup START_SEQ_NUM,also lose first sequence
|
||||
when receiver unordered sequence ;
|
||||
2012-05-11 v0.19 1)fix sender's smooth default interval zero bug;
|
||||
2)fix FORCE_EST_INTERVAL 20min(1000000ms) bug,sho
|
||||
3)fix receiver's ack smooth default interval 10s bug;
|
||||
2012-05-24 v0.20 1)fix smooth block may copy expired father stream bug;
|
||||
2)use mutex_lock instead of try_lock to get smoothed block;
|
||||
3)add thread smooth space limit;
|
||||
2012-06-11 v0.21 1)add choke recv timeout feature;
|
||||
2012-06-18 v0.22 1)businesman_limit.h TIMEOUT_RECV_STREAM_USEC init read array overflow;
|
||||
2)smooth send and reliable send stream expire after send data,a busy receiver may drop lazy
|
||||
sender's packet,move expire operation in front of send;
|
||||
2012-07-24 v1.0 1)check slice_len in is_bizman_packet;
|
||||
2013-03-20 v1.01 1)shorten mutex contension area in recv;
|
||||
2)fix add_raw_packet bugs of filling wrong sequence in ack packet,which caused 250Mbps bottleneck;
|
||||
2013-05-14 v1.02 fix unreliable packet receive dead lock bug in add_raw_packet,caused by v1.01 shorten mutex improvement;
|
||||
2013-06-19 v1.03 1)fix isolate_recv_record dead lock;
|
||||
2)last_send_time type is uint ,cause overflow,change to time_tick_t;
|
||||
2013-07-02 v1.04 v1.01 shorten mutex proved wrong,called deadlock,backward.
|
||||
2013-10-28 v1.05 Not set chunk end after read uncomplete slice.
|
||||
TODO: 1)add select unreachable error;
|
||||
2)add send file interface,save one memory copy time;
|
||||
3)add max memory used limited;
|
||||
|
||||
NOTICE: 1)recv function is NOT thread safe,MUST use your own mutex lock protect the handle;
|
||||
2)send function is thread safe when you send with differenct thread id,but call send function\
|
||||
with the same thread id in different thread is NOT safe;
|
||||
3)unsigned short port is host order,unsigned int ip address is network layer.
|
||||
4)compatible with gcc,link with -lstdc++
|
||||
*/
|
||||
#ifndef _BIZMAN_HEADER_INCLUDE_
|
||||
#define _BIZMAN_HEADER_INCLUDE_
|
||||
|
||||
//initial flag
|
||||
#define BIZMAN_SENDER_ACTIVE 0x01
|
||||
#define BIZMAN_RECEIVER_ACTIVE 0x02
|
||||
|
||||
#define BIZMAN_CHUNK_RECEIVE 0x08
|
||||
#define BIZMAN_CHOKE_RECEIVE 0x10
|
||||
|
||||
|
||||
//set option
|
||||
#define BIZMAN_OPT_SOCKET_INTERFACE_NAME 0x00
|
||||
#define BIZMAN_OPT_PAG_INTERFACE_NAME 0x01
|
||||
|
||||
//set parameter
|
||||
#define BIZMAN_PARAMETER_SEND_SMOOTH_TIME_MSEC 0x01
|
||||
#define BIZMAN_PARAMETER_RESEND_BASE_MSEC 0x02
|
||||
#define BIZMAN_PARAMETER_RESEND_TIMES 0x03 //5 at most
|
||||
#define BIZMAN_PARAMETER_SEND_CACHE_PKTS_LIMIT 0x04
|
||||
#define BIZMAN_PARAMETER_ACK_ACCUMULATE_NUM 0x05
|
||||
#define BIZMAN_PARAMETER_ACK_ACCUMULATE_MSEC 0x06
|
||||
#define BIZMAN_PARAMETER_SEND_WINDOWSIZE 0x07
|
||||
#define BIZMAN_PARAMETER_RECV_WINDOWSIZE 0x08
|
||||
#define BIZMAN_PARAMETER_ACK_SMOOTH_TIME_MSEC 0x09
|
||||
#define BIZMAN_PARAMETER_FROZEN_STREAM_MSEC 0x0a
|
||||
#define BIZMAN_PARAMETER_SMOOTH_CACHE_PKTS_LIMIT 0x0b
|
||||
|
||||
#define BIZMAN_PARAMETER_CHUNK_RECEIVE 0x10
|
||||
#define BIZMAN_PARAMETER_CHOKE_RECEIVE 0x11
|
||||
#define BIZMAN_PARAMETER_CHOKE_RECV_TIMEOUT_MSEC 0x12
|
||||
|
||||
//send flag
|
||||
#define BIZMAN_RELIABLE_SEND 0x01
|
||||
#define BIZMAN_UNRELIABLE_SEND 0x00
|
||||
#define BIZMAN_LAST_PKT 0x02
|
||||
#define BIZMAN_PUSH_SEND 0x04
|
||||
#define BIZMAN_SMOOTH_DEST 0x08
|
||||
|
||||
|
||||
//recv flag
|
||||
#define BIZMAN_READ_CRAM 0x00
|
||||
#define BIZMAN_READ_STREAM 0x01
|
||||
#define BIZMAN_READ_CHUNK 0x02
|
||||
|
||||
//stat
|
||||
#define BIZMAN_STAT_FIRST_SEND_PKTS 0x01
|
||||
#define BIZMAN_STAT_FIRST_RESEND_PKTS 0x02
|
||||
#define BIZMAN_STAT_LAST_RESEND 0x03
|
||||
#define BIZMAN_STAT_MEM_DROPPED 0x04
|
||||
#define BIZMAN_STAT_FROZEN_DROPPED 0x05
|
||||
#define BIZMAN_STAT_ACK_PKT_NUM 0x06
|
||||
#define BIZMAN_STAT_FIRST_SEND_STREAM 0x07
|
||||
#define BIZMAN_STAT_FIRST_RESEND_STREAM 0x08
|
||||
#define BIZMAN_STAT_ACTIVE_STREAM 0x09
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
/*
|
||||
*return an unintialized handle when success;
|
||||
*return NULL when failed.
|
||||
*/
|
||||
void *bizman_get_handle(void);
|
||||
void bizman_destroy_handle(void * raw_handle);
|
||||
/*
|
||||
BIZMAN_SENDER_ACTIVE:0x01;BIZMAN_RECEIVER_ACTIVE:0x02;BIZMAN_PAG_USE:0x04;
|
||||
*/
|
||||
int bizman_set_handle(void* raw_handle,unsigned short flags);
|
||||
int bizman_set_handle_option(void* raw_handle,int option_type, const char* option_value);
|
||||
int bizman_set_handle_parameter(void* raw_handle,int type, unsigned int value);
|
||||
//only used on sender
|
||||
int bizman_set_pkts_cached_limit(void* raw_handle,unsigned long long cached_pkts_limit);
|
||||
|
||||
//unsigned short port is host order,unsigned int ip address is network layer.
|
||||
int bizman_listen(void* raw_handle,unsigned short port);
|
||||
int bizman_init_handle(void* raw_handle);
|
||||
|
||||
int bizman_recv(void* raw_handle,char* buff,int buf_len,unsigned int *src_ip,unsigned short *src_port,unsigned int *stream_id,unsigned int* is_complete);
|
||||
int bizman_send(void* raw_handle,unsigned int thread_id,unsigned int dest_ip,unsigned short dest_port,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags);
|
||||
int bizman_multi_send(void* raw_handle,unsigned int thread_id,const unsigned int *dest_ip,const unsigned short *dest_port,unsigned int dest_num,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags);
|
||||
unsigned long long bizman_stat(void* raw_handle,int type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
34
src/support/Businessman/businessman_base.h
Normal file
34
src/support/Businessman/businessman_base.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef _BIZMAN_BASE_H_INCLUDE_
|
||||
#define _BIZMAN_BASE_H_INCLUDE_
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_packet.h"
|
||||
typedef struct _businessman_external_send_task{
|
||||
uint32 *dest_ip;
|
||||
uint16 *dest_port;
|
||||
uint32 dest_num;
|
||||
uint64 app_id;
|
||||
const char* data;
|
||||
int len;
|
||||
uint16 flags;
|
||||
}external_send_task_t;
|
||||
typedef struct _businessman_internal_send_task{
|
||||
uint32 *dest_ip;
|
||||
uint16 *dest_port;
|
||||
uint32 dest_num;
|
||||
uint32 stream_id;
|
||||
uint32 *sub_stream_id;
|
||||
send_data_refer_t* data;
|
||||
int is_reliable;
|
||||
uint16 flags;
|
||||
}internal_send_task_t;
|
||||
typedef struct _businessman_sub_task{
|
||||
uint32 dest_ip;
|
||||
uint16 dest_port;
|
||||
uint32 stream_id;
|
||||
send_data_refer_t* refer_index;
|
||||
int is_reliable;
|
||||
uint16 flags;
|
||||
}sub_send_task_t;
|
||||
#endif //_BIZMAN_BASE_H_INCLUDE_
|
||||
|
||||
671
src/support/Businessman/businessman_core.cpp
Normal file
671
src/support/Businessman/businessman_core.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
Businessman Data Exchange System Top Level structure
|
||||
*/
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>//using memset
|
||||
#include <pthread.h>
|
||||
#include <errno.h> //errorno
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_packet.h"
|
||||
#include "businessman_error.h"
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "smooth_send.h"
|
||||
#include "reliable_send.h"
|
||||
#include "reliable_recv.h"
|
||||
#include "stream_recover.h"
|
||||
#include "network_layer.h"
|
||||
#include "businessman_core.h"
|
||||
#include "bizman.h"
|
||||
int assign_task(void *(*worker)(void *),void * params)
|
||||
{
|
||||
pthread_t thread_desc;
|
||||
pthread_attr_t attr;
|
||||
memset(&thread_desc, 0, sizeof(thread_desc));
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
|
||||
if(0 != pthread_attr_init(&(attr))) {
|
||||
set_user_error("pthread_attr_init(): %d %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_attr_setdetachstate(&(attr), PTHREAD_CREATE_DETACHED)) {
|
||||
set_user_error("pthread_attr_setdetachstate(): %d %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(0 != pthread_create(&(thread_desc), &(attr), (void *(*)(void *))(worker), (void *)(params))) {
|
||||
set_user_error("pthread_create(): %d %s", errno, strerror(errno));
|
||||
pthread_attr_destroy(&(attr));
|
||||
return -1;
|
||||
}
|
||||
pthread_attr_destroy(&(attr));
|
||||
return 0;
|
||||
|
||||
}
|
||||
unsigned long long make_app_id_by_dest(unsigned int dest_ip,unsigned short dest_port)
|
||||
{
|
||||
unsigned long long app_id;
|
||||
app_id=dest_ip;
|
||||
app_id<<=32;
|
||||
app_id+=dest_port;
|
||||
return app_id;
|
||||
}
|
||||
external_send_task_t* create_external_send_task(const char* data,int len,uint64 app_id,uint16 flags,const uint32* dest_ip,const uint16*dest_port,uint32 dest_num)
|
||||
{
|
||||
external_send_task_t* send_task=NULL;
|
||||
send_task=(external_send_task_t*)b_malloc(sizeof(external_send_task_t));
|
||||
send_task->data=data;
|
||||
send_task->len=len;
|
||||
send_task->app_id=app_id;
|
||||
send_task->flags=flags;
|
||||
send_task->dest_num=dest_num;
|
||||
send_task->dest_ip=(unsigned int *)b_malloc(dest_num*sizeof(*dest_ip));
|
||||
memcpy(send_task->dest_ip,dest_ip,dest_num*sizeof(*dest_ip));
|
||||
send_task->dest_port=(unsigned short *)b_malloc(dest_num*sizeof(*dest_port));
|
||||
memcpy(send_task->dest_port,dest_port,dest_num*sizeof(*dest_port));
|
||||
return send_task;
|
||||
}
|
||||
void destroy_external_send_task(external_send_task_t* send_task)
|
||||
{
|
||||
free(send_task->dest_ip);
|
||||
send_task->dest_ip=NULL;
|
||||
free(send_task->dest_port);
|
||||
send_task->dest_port=NULL;
|
||||
send_task->dest_num=0;
|
||||
free(send_task);
|
||||
}
|
||||
char* bizman_get_error_string(void){
|
||||
return get_error_string();
|
||||
}
|
||||
|
||||
void * bizman_core_send_thread(void* param)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)param;
|
||||
bizman_send_space_t* send_space=handle->send_space;
|
||||
// smooth_block_t* already_smoothed_block=NULL;
|
||||
internal_send_task_t already_smoothed_task;
|
||||
sub_send_task_t sub_already_smoothed_task,reliable_send_task;
|
||||
void *reliable_send_transition_handle=NULL;
|
||||
char ack_buf[MTU_SIZE];
|
||||
int i=0;
|
||||
unsigned int j=0;
|
||||
int recv_ack_len=0;
|
||||
unsigned int ack_src_ip;
|
||||
unsigned short ack_src_port;
|
||||
int is_thread_idle=TRUE;
|
||||
/*
|
||||
int s=0;
|
||||
cpu_set_t cpuset;
|
||||
pthread_t thread;
|
||||
thread = pthread_self();
|
||||
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(8, &cpuset);
|
||||
s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
|
||||
if (s != 0)
|
||||
printf("bizman:pthread_setaffinity_np failed.\n");
|
||||
|
||||
s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
|
||||
if (s != 0)
|
||||
printf("bizman:pthread_getaffinity_np failed.\n");
|
||||
|
||||
printf("Set returned by pthread_getaffinity_np() contained:\n");
|
||||
for (i = 0; i < CPU_SETSIZE; i++)
|
||||
if (CPU_ISSET(i, &cpuset))
|
||||
printf(" CPU %d\n", i);
|
||||
*/
|
||||
while(handle->should_sender_active==TRUE)
|
||||
{
|
||||
is_thread_idle=TRUE;
|
||||
memset(&reliable_send_task,0,sizeof(reliable_send_task));
|
||||
//put smoothed block to reliable send space
|
||||
for(i=0;i<MAX_THREAD_SUPPORT;i++)
|
||||
{
|
||||
if(send_space->thread_smooth_space[i]!=NULL)
|
||||
{
|
||||
memset(&already_smoothed_task,0,sizeof(already_smoothed_task));
|
||||
while(get_smoothed_task(send_space->thread_smooth_space[i],&already_smoothed_task)!=0)
|
||||
{
|
||||
for(j=0;j<already_smoothed_task.dest_num;j++)
|
||||
{
|
||||
memset(&sub_already_smoothed_task,0,sizeof(sub_already_smoothed_task));
|
||||
sub_already_smoothed_task.stream_id=already_smoothed_task.sub_stream_id[j];
|
||||
sub_already_smoothed_task.dest_ip=already_smoothed_task.dest_ip[j];
|
||||
sub_already_smoothed_task.dest_port=already_smoothed_task.dest_port[j];
|
||||
sub_already_smoothed_task.flags=already_smoothed_task.flags;
|
||||
sub_already_smoothed_task.is_reliable=already_smoothed_task.is_reliable;
|
||||
sub_already_smoothed_task.refer_index=already_smoothed_task.data;
|
||||
if(0>join_to_reliable_send(send_space->core_reliable_space,&sub_already_smoothed_task))
|
||||
{
|
||||
free_refer_and_data(already_smoothed_task.data);
|
||||
sub_already_smoothed_task.refer_index=NULL;
|
||||
}
|
||||
|
||||
}
|
||||
free(already_smoothed_task.dest_ip);
|
||||
free(already_smoothed_task.dest_port);
|
||||
free(already_smoothed_task.sub_stream_id);
|
||||
memset(&already_smoothed_task,0,sizeof(already_smoothed_task));
|
||||
is_thread_idle=FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//do reliable send
|
||||
for(i=0;i<MAX_DAT_SEND_PER_LOOP;i++)
|
||||
{
|
||||
reliable_send_transition_handle=get_reliable_send_task(send_space->core_reliable_space, &reliable_send_task);
|
||||
if(reliable_send_transition_handle!=NULL)
|
||||
{
|
||||
reliable_send_task.refer_index->packet->id=reliable_send_task.stream_id;
|
||||
do_actual_send(handle->network_layer,reliable_send_task.dest_ip, reliable_send_task.dest_port, (const char*)(reliable_send_task.refer_index->packet), reliable_send_task.refer_index->data_len);
|
||||
recycle_transition_handle(send_space->core_reliable_space,reliable_send_transition_handle);
|
||||
is_thread_idle=FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//do ack received operation
|
||||
for(i=0;i<MAX_ACK_RECV_PER_LOOP;i++){
|
||||
memset(ack_buf,0,sizeof(ack_buf));
|
||||
recv_ack_len=do_actual_recv(handle->network_layer, &ack_src_ip, &ack_src_port, ack_buf, sizeof(ack_buf));
|
||||
if(recv_ack_len>0&&TRUE==is_bizman_packet((bizman_packet_t*)ack_buf))
|
||||
{
|
||||
is_thread_idle=FALSE;
|
||||
handle_ack(send_space->core_reliable_space,(bizman_packet_t*)ack_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(is_thread_idle==TRUE)
|
||||
{
|
||||
usleep(10);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void * bizman_core_recv_thread(void* param)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)param;
|
||||
bizman_recv_space_t* recv_space=handle->recv_space;
|
||||
int i=0;
|
||||
unsigned int data_src_ip;
|
||||
unsigned short data_src_port;
|
||||
char* dat_packet_buf=NULL;
|
||||
ack_task_t ack_task;
|
||||
external_send_task_t* ack_to_smooth_task=NULL;
|
||||
internal_send_task_t ack_smoothed_task;
|
||||
uint64 ack_app_id=0;
|
||||
char ack_packet_buf[MTU_SIZE];
|
||||
int dat_packet_length=0;
|
||||
int is_thread_idle=TRUE;
|
||||
while(handle->should_receiver_active==TRUE)
|
||||
{
|
||||
is_thread_idle=TRUE;
|
||||
for(i=0;i<MAX_DAT_RECV_PER_LOOP;i++)
|
||||
{
|
||||
dat_packet_buf=(char*)b_malloc(sizeof(char)*MTU_SIZE);
|
||||
dat_packet_length=do_actual_recv(handle->network_layer,&data_src_ip, &data_src_port,dat_packet_buf, MTU_SIZE);
|
||||
if(dat_packet_length>0)
|
||||
{
|
||||
is_thread_idle=FALSE;
|
||||
handle->recv_space->stat_packet_recv_num++;
|
||||
if(TRUE==is_bizman_packet((bizman_packet_t*) dat_packet_buf))
|
||||
{
|
||||
add_raw_packet(recv_space->reliable_recv_space,data_src_ip,data_src_port,(bizman_packet_t*) dat_packet_buf,dat_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->recv_space->stat_invalid_packet_recv_num++;
|
||||
free(dat_packet_buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free(dat_packet_buf);
|
||||
//break;
|
||||
}
|
||||
}
|
||||
for(i=0;i<MAX_ACK_RECV_PER_LOOP;i++)
|
||||
{
|
||||
memset(&ack_task,0,sizeof(ack_task));
|
||||
if(get_ack_task(recv_space->reliable_recv_space, &ack_task))
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG_DETAILS
|
||||
printf("Send ACK %llu:stream=%d seq=%d\n",get_time_tick(),ack_task.stream_id,ack_task.sequence);
|
||||
#endif
|
||||
is_thread_idle=FALSE;
|
||||
ack_app_id=make_app_id_by_dest(ack_task.dest_ip,ack_task.dest_port);
|
||||
memcpy(ack_packet_buf,(char*)(&(ack_task.stream_id)),sizeof(ack_task.stream_id));
|
||||
memcpy(ack_packet_buf+sizeof(ack_task.stream_id),(char*)(&(ack_task.sequence)),sizeof(ack_task.sequence));
|
||||
ack_to_smooth_task=create_external_send_task(ack_packet_buf,
|
||||
sizeof(ack_task.stream_id)+sizeof(ack_task.sequence),
|
||||
ack_app_id,
|
||||
0,
|
||||
&(ack_task.dest_ip),
|
||||
&(ack_task.dest_port),
|
||||
1);
|
||||
smooth_block(recv_space->ack_send_smooth_space, ack_to_smooth_task);
|
||||
destroy_external_send_task(ack_to_smooth_task);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i=0;i<MAX_ACK_RECV_PER_LOOP;i++)
|
||||
{
|
||||
if(get_smoothed_task(recv_space->ack_send_smooth_space,&ack_smoothed_task))
|
||||
{
|
||||
is_thread_idle=FALSE;
|
||||
ack_smoothed_task.data->packet->flags|=FLAG_ACK_PKT;
|
||||
do_actual_send(handle->network_layer, ack_smoothed_task.dest_ip[0],
|
||||
ack_smoothed_task.dest_port[0],
|
||||
(const char*)(ack_smoothed_task.data->packet),
|
||||
ack_smoothed_task.data->data_len);
|
||||
handle->recv_space->stat_ack_send_num++;
|
||||
free(ack_smoothed_task.dest_ip);
|
||||
free(ack_smoothed_task.dest_port);
|
||||
free(ack_smoothed_task.sub_stream_id);
|
||||
free_refer_and_data(ack_smoothed_task.data);
|
||||
memset(&ack_smoothed_task,0,sizeof(ack_smoothed_task));
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(is_thread_idle==TRUE)
|
||||
{
|
||||
usleep(10);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bizman_send_space_t *bizman_create_sender(unsigned int flags){
|
||||
|
||||
bizman_send_space_t* sender=NULL;
|
||||
|
||||
sender=(bizman_send_space_t*)b_malloc(sizeof(bizman_send_space_t));
|
||||
if(sender==NULL)
|
||||
{
|
||||
set_error(ERROR_TYPE_OUTOFMEM);
|
||||
return NULL;
|
||||
}
|
||||
sender->core_reliable_space=create_reliable_send_space();
|
||||
if(sender->core_reliable_space==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
sender->send_smooth_timeout_tick=DEFAULT_TIMEOUT_SMOOTH_BLOCK_USEC/TIME_TICK_STEP_USEC;
|
||||
return sender;
|
||||
|
||||
}
|
||||
void bizman_destroy_sender(bizman_send_space_t * sender)
|
||||
{
|
||||
int i=0;
|
||||
for(i=0;i<MAX_THREAD_SUPPORT;i++){
|
||||
if(sender->thread_smooth_space[i]!=NULL)
|
||||
{
|
||||
destroy_smooth_send_space(sender->thread_smooth_space[i]);
|
||||
}
|
||||
}
|
||||
destroy_reliable_send_space(sender->core_reliable_space);
|
||||
free(sender);
|
||||
}
|
||||
bizman_recv_space_t *bizman_create_receiver(unsigned int flags)
|
||||
{
|
||||
bizman_recv_space_t*receiver=NULL;
|
||||
receiver=(bizman_recv_space_t *)b_malloc(sizeof(bizman_recv_space_t));
|
||||
if(receiver==NULL)
|
||||
{
|
||||
set_error(ERROR_TYPE_OUTOFMEM);
|
||||
return NULL;
|
||||
}
|
||||
receiver->reliable_recv_space=create_reliable_recv_space();
|
||||
if(receiver->reliable_recv_space==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
receiver->ack_send_smooth_space=create_smooth_send_space();
|
||||
|
||||
receiver->stream_recover_space=get_stream_recover_space();
|
||||
if(receiver->stream_recover_space==NULL)
|
||||
{
|
||||
//return NULL;
|
||||
}
|
||||
if(flags&BIZMAN_CHUNK_RECEIVE)
|
||||
{
|
||||
receiver->reliable_recv_space->chunk_mode=TRUE;
|
||||
}
|
||||
if(flags&BIZMAN_CHOKE_RECEIVE)
|
||||
{
|
||||
receiver->reliable_recv_space->choke_mode=TRUE;
|
||||
}
|
||||
return receiver;
|
||||
}
|
||||
void bizman_destroy_receiver(bizman_recv_space_t *receiver)
|
||||
{
|
||||
reliable_recv_space_t* reliable_recv_space=receiver->reliable_recv_space;
|
||||
destroy_reliable_recv_space(reliable_recv_space);
|
||||
|
||||
}
|
||||
/*return 0 when success ,return -1 when failed*/
|
||||
int bizman_listen(void* raw_handle,unsigned short port){
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
if(NULL==handle)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
if(FALSE==handle->should_receiver_active)
|
||||
{
|
||||
// handle->should_receiver_active=TRUE;
|
||||
}
|
||||
return set_network_listen_port(handle->network_layer, port);
|
||||
|
||||
}
|
||||
/*return NULL when failed*/
|
||||
void *bizman_get_handle(void){
|
||||
bizman_handle_t* handle=NULL;
|
||||
handle=(bizman_handle_t*)b_malloc(sizeof(bizman_handle_t));
|
||||
if(handle==NULL)
|
||||
{
|
||||
set_error(ERROR_TYPE_OUTOFMEM);
|
||||
return NULL;
|
||||
}
|
||||
handle->network_layer=get_network_handle();
|
||||
if(handle->network_layer==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (void*)handle;
|
||||
}
|
||||
void bizman_destroy_handle(void * raw_handle)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
if(handle->recv_space!=NULL)
|
||||
{
|
||||
handle->should_receiver_active=FALSE;
|
||||
bizman_destroy_receiver(handle->recv_space);
|
||||
}
|
||||
if(handle->send_space!=NULL)
|
||||
{
|
||||
handle->should_sender_active=FALSE;
|
||||
bizman_destroy_sender(handle->send_space);
|
||||
}
|
||||
destroy_network_handle(handle->network_layer);
|
||||
}
|
||||
/*return 0 when success ,return -1 when failed*/
|
||||
int bizman_set_handle(void* raw_handle,unsigned short flags)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
if(NULL==handle)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
handle->flags|=flags;
|
||||
if(flags&BIZMAN_SENDER_ACTIVE)
|
||||
{
|
||||
handle->send_space=bizman_create_sender(handle->flags);
|
||||
handle->should_sender_active=TRUE;
|
||||
|
||||
}
|
||||
if(flags&BIZMAN_RECEIVER_ACTIVE)
|
||||
{
|
||||
handle->recv_space=bizman_create_receiver(handle->flags);
|
||||
handle->should_receiver_active=TRUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int bizman_set_handle_parameter(void * raw_handle, int type, unsigned int value)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
if(NULL==handle)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
if(handle->send_space==NULL&&handle->recv_space==NULL)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
switch(type)
|
||||
{
|
||||
case BIZMAN_PARAMETER_ACK_ACCUMULATE_MSEC:
|
||||
handle->recv_space->reliable_recv_space->accumulate_ack_timeout_tick=value*1000/TIME_TICK_STEP_USEC;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_ACK_ACCUMULATE_NUM:
|
||||
handle->recv_space->reliable_recv_space->accumulate_ack_num=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_RECV_WINDOWSIZE:
|
||||
handle->recv_space->reliable_recv_space->receive_window_size=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_ACK_SMOOTH_TIME_MSEC:
|
||||
handle->recv_space->ack_send_smooth_space->smooth_timeout_tick=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_RESEND_BASE_MSEC:
|
||||
handle->send_space->core_reliable_space->resend_base_tick=value*1000/TIME_TICK_STEP_USEC;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_RESEND_TIMES:
|
||||
if(value<=MAX_RESEND_TIMES)
|
||||
{
|
||||
handle->send_space->core_reliable_space->resend_times=value;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case BIZMAN_PARAMETER_SEND_WINDOWSIZE:
|
||||
handle->send_space->core_reliable_space->send_widow_size=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_SEND_SMOOTH_TIME_MSEC:
|
||||
handle->send_space->send_smooth_timeout_tick=value*1000/TIME_TICK_STEP_USEC;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_SEND_CACHE_PKTS_LIMIT:
|
||||
handle->send_space->core_reliable_space->cached_pkts_num_limit=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_CHOKE_RECEIVE:
|
||||
handle->recv_space->reliable_recv_space->choke_mode=TRUE;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_CHUNK_RECEIVE:
|
||||
handle->recv_space->reliable_recv_space->chunk_mode=TRUE;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_FROZEN_STREAM_MSEC:
|
||||
handle->send_space->stream_frozen_stream_time_tick=value*1000/TIME_TICK_STEP_USEC;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_SMOOTH_CACHE_PKTS_LIMIT:
|
||||
handle->send_space->cached_smooth_pkts_limit=value;
|
||||
break;
|
||||
case BIZMAN_PARAMETER_CHOKE_RECV_TIMEOUT_MSEC:
|
||||
handle->recv_space->reliable_recv_space->choke_timeout_mili_seconds=value;
|
||||
break;
|
||||
default:
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int bizman_set_handle_option(void* raw_handle,int option_type, const char* option_value)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
int ret=0;
|
||||
switch(option_type)
|
||||
{
|
||||
case BIZMAN_OPT_SOCKET_INTERFACE_NAME:
|
||||
set_network_interface(handle->network_layer, BIZMAN_INTERFACE_SOCKET,option_value);
|
||||
break;
|
||||
case BIZMAN_OPT_PAG_INTERFACE_NAME:
|
||||
set_network_interface(handle->network_layer, BIZMAN_INTERFACE_PAG,NULL);
|
||||
break;
|
||||
default:
|
||||
set_user_error("invalid option type.");
|
||||
ret=-1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int bizman_set_pkts_cached_limit(void* raw_handle,unsigned long long cached_pkts_limit)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
handle->sender_cached_pkts_limit=cached_pkts_limit;
|
||||
return 1;
|
||||
}
|
||||
/*return 0 when success ,return -1 when failed*/
|
||||
int bizman_init_handle(void* raw_handle)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
if(NULL==handle)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
if(0>init_network_layer(handle->network_layer))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
bizman_timer_start();
|
||||
if(handle->should_sender_active)
|
||||
{
|
||||
if(NULL==handle->send_space)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(0>assign_task((void *(*)(void *))(bizman_core_send_thread), (void *)handle))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(handle->should_receiver_active)
|
||||
{
|
||||
if(NULL==handle->recv_space)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(0>assign_task((void *(*)(void *))(bizman_core_recv_thread), (void *)handle))
|
||||
{
|
||||
return -1;;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bizman_send_stream(bizman_send_space_t* sender,unsigned int thread_id,const unsigned int *dest_ip,const unsigned short* dest_port,unsigned int dest_num,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags)
|
||||
{
|
||||
smooth_space_t* thread_smooth_space=NULL;
|
||||
|
||||
external_send_task_t *send_task;
|
||||
int ret;
|
||||
if(sender==NULL)
|
||||
{
|
||||
set_error(ERROR_TYPE_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(sender->thread_smooth_space[thread_id%MAX_THREAD_SUPPORT]==NULL)
|
||||
{
|
||||
thread_smooth_space=create_smooth_send_space();
|
||||
thread_smooth_space->smooth_timeout_tick=sender->send_smooth_timeout_tick;
|
||||
thread_smooth_space->cache_smooth_pkts_limit=sender->cached_smooth_pkts_limit;
|
||||
if(thread_smooth_space==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sender->thread_smooth_space[thread_id%MAX_THREAD_SUPPORT]=thread_smooth_space;
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_smooth_space=sender->thread_smooth_space[thread_id%MAX_THREAD_SUPPORT];
|
||||
}
|
||||
send_task=create_external_send_task(data,len,app_id, flags, dest_ip,dest_port,dest_num);
|
||||
|
||||
ret=smooth_block(thread_smooth_space, send_task);
|
||||
destroy_external_send_task(send_task);
|
||||
send_task=NULL;
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int bizman_recv(void* raw_handle,char* buff,int buf_len,unsigned int *src_ip,unsigned short *src_port,unsigned int *stream_id,unsigned int* is_complete)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
bizman_recv_space_t* receiver=handle->recv_space;
|
||||
return copy_recv_data(receiver->reliable_recv_space, buff,buf_len, src_ip,src_port,stream_id,is_complete);
|
||||
}
|
||||
|
||||
int bizman_send(void* raw_handle,unsigned int thread_id,unsigned int dest_ip,unsigned short dest_port,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
bizman_send_space_t* sender=handle->send_space;
|
||||
if(flags&BIZMAN_SMOOTH_DEST)
|
||||
{
|
||||
app_id=make_app_id_by_dest(dest_ip,dest_port);
|
||||
}
|
||||
return bizman_send_stream(sender,thread_id,&dest_ip,&dest_port,1,
|
||||
data,len,app_id,flags);
|
||||
}
|
||||
int bizman_multi_send(void* raw_handle,unsigned int thread_id,const unsigned int *dest_ip,const unsigned short *dest_port,unsigned int dest_num,
|
||||
const char*data,unsigned int len,unsigned long long app_id,unsigned short flags)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
bizman_send_space_t* sender=handle->send_space;
|
||||
return bizman_send_stream(sender,thread_id,dest_ip,dest_port,dest_num,
|
||||
data,len,app_id,flags);
|
||||
}
|
||||
unsigned long long bizman_stat(void* raw_handle,int type)
|
||||
{
|
||||
bizman_handle_t* handle=(bizman_handle_t*)raw_handle;
|
||||
bizman_send_space_t* sender=handle->send_space;
|
||||
unsigned long long result=0;
|
||||
switch(type)
|
||||
{
|
||||
case BIZMAN_STAT_FIRST_SEND_PKTS:
|
||||
result=stat_first_send_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_FIRST_RESEND_PKTS:
|
||||
result=stat_first_resend_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_LAST_RESEND:
|
||||
result=stat_last_resend_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_MEM_DROPPED:
|
||||
result=stat_dropped_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_FROZEN_DROPPED:
|
||||
result=stat_frozen_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_ACK_PKT_NUM:
|
||||
result=stat_ack_packet_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_FIRST_SEND_STREAM:
|
||||
result=stat_frist_send_stream_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_FIRST_RESEND_STREAM:
|
||||
result=stat_frist_resend_stream_count(sender->core_reliable_space);
|
||||
break;
|
||||
case BIZMAN_STAT_ACTIVE_STREAM:
|
||||
result=stat_active_stream_count(sender->core_reliable_space);
|
||||
break;
|
||||
default:
|
||||
printf("unkonwn stat type\n");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
33
src/support/Businessman/businessman_core.h
Normal file
33
src/support/Businessman/businessman_core.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "smooth_send.h"
|
||||
#include "reliable_send.h"
|
||||
#include "reliable_recv.h"
|
||||
#include "stream_recover.h"
|
||||
#include "network_layer.h"
|
||||
#include "businessman_time.h"
|
||||
typedef struct _businessman_send_space_t{
|
||||
smooth_space_t *thread_smooth_space[MAX_THREAD_SUPPORT];
|
||||
reliable_send_space_t *core_reliable_space;
|
||||
time_tick_t send_smooth_timeout_tick;
|
||||
time_tick_t stream_frozen_stream_time_tick;
|
||||
unsigned long long cached_smooth_pkts_limit;
|
||||
}bizman_send_space_t;
|
||||
typedef struct _businessman_recv_space_t{
|
||||
recover_space_t *stream_recover_space;
|
||||
reliable_recv_space_t* reliable_recv_space;
|
||||
smooth_space_t*ack_send_smooth_space;
|
||||
unsigned long long stat_packet_recv_num;
|
||||
unsigned long long stat_ack_send_num;
|
||||
unsigned long long stat_invalid_packet_recv_num;
|
||||
}bizman_recv_space_t;
|
||||
typedef struct _businessman_work_space_t{
|
||||
unsigned int should_sender_active;
|
||||
unsigned int should_receiver_active;
|
||||
unsigned int flags;
|
||||
bizman_recv_space_t *recv_space;
|
||||
bizman_send_space_t *send_space;
|
||||
network_space_t* network_layer;
|
||||
unsigned long long sender_cached_pkts_limit;
|
||||
}bizman_work_space_t;
|
||||
|
||||
typedef bizman_work_space_t bizman_handle_t;
|
||||
|
||||
49
src/support/Businessman/businessman_error.cpp
Normal file
49
src/support/Businessman/businessman_error.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>//va_start
|
||||
#include <string.h>//snprintf memset
|
||||
#include "businessman_error.h"
|
||||
const char * error_define_string[]={"no error detected","socket error","out of mem","invalid parameter"};
|
||||
static int g_error=ERROR_TYPE_NOERROR;
|
||||
char user_error_string[4096];
|
||||
char error_location[1024];
|
||||
char error_output_string[4096];
|
||||
void set_user_error(char * format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
memset(user_error_string,0,sizeof(user_error_string));
|
||||
va_start(ap, format);
|
||||
vsnprintf(user_error_string, sizeof(user_error_string), format, ap);
|
||||
va_end(ap);
|
||||
g_error=ERROR_TYPE_USER;
|
||||
fprintf(stderr,"Bizman Error:%s\n",user_error_string);
|
||||
}
|
||||
void set_unreable(char* fromat, ...)
|
||||
{
|
||||
g_error=ERROR_TYPE_DEST_UNREACHABLE;
|
||||
}
|
||||
void set_bizman_error(int error_type,const char*source_file,int code_line_num,const char*function_name){
|
||||
g_error=error_type;
|
||||
memset(error_location,0,sizeof(error_location));
|
||||
snprintf(error_location,sizeof(error_location),"%s %d %s",source_file,code_line_num,function_name);
|
||||
fprintf(stderr,"Bizman Error:%s\n",error_location);
|
||||
}
|
||||
char * get_error_string(){
|
||||
char* result=NULL;
|
||||
if(g_error==ERROR_TYPE_USER)
|
||||
{
|
||||
result= user_error_string;
|
||||
}
|
||||
else if(g_error==ERROR_TYPE_DEST_UNREACHABLE)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(error_output_string,0,sizeof(error_output_string));
|
||||
snprintf(error_output_string,sizeof(error_output_string),"bizman error: %s %s",error_define_string[g_error],error_location);
|
||||
result= error_output_string;
|
||||
}
|
||||
g_error=ERROR_TYPE_NOERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
17
src/support/Businessman/businessman_error.h
Normal file
17
src/support/Businessman/businessman_error.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _BIZMAN_ERROR_H_INCLUDE_
|
||||
#define _BIZMAN_ERROR_H_INCLUDE_
|
||||
#define set_error(s) set_bizman_error(s,__FILE__,__LINE__,__PRETTY_FUNCTION__)
|
||||
enum BusinessmanErrorType{
|
||||
ERROR_TYPE_USER=-1,
|
||||
ERROR_TYPE_NOERROR=0,
|
||||
ERROR_TYPE_SOCKET,
|
||||
ERROR_TYPE_OUTOFMEM,
|
||||
ERROR_TYPE_INVALID_PARAMETER,
|
||||
ERROR_TYPE_DEST_UNREACHABLE
|
||||
};
|
||||
|
||||
void set_user_error(char * format, ...);
|
||||
void set_bizman_error(int error_type,const char*source_file,int code_line_num,const char*function_name);
|
||||
char * get_error_string();
|
||||
#endif//_BIZMAN_ERROR_H_INCLUDE_
|
||||
|
||||
70
src/support/Businessman/businessman_limit.h
Normal file
70
src/support/Businessman/businessman_limit.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef _BUSINESSMAN_LIMIT_INCLUDE_H_
|
||||
#define _BUSINESSMAN_LIMIT_INCLUDE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "businessman_time.h"
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif //end TURE
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif //end false
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
#ifndef container_of
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof(((type *)0)->member) * __mptr = (ptr); \
|
||||
(type *)((char *)__mptr - offsetof(type, member)); })
|
||||
#endif
|
||||
|
||||
const int MAX_THREAD_SUPPORT=64;
|
||||
|
||||
|
||||
|
||||
const int MAX_DAT_SEND_PER_LOOP=300;
|
||||
const int MAX_ACK_RECV_PER_LOOP=6;
|
||||
const int MAX_DAT_RECV_PER_LOOP=MAX_DAT_SEND_PER_LOOP;
|
||||
const int MAX_ACK_SEND_PER_LOOP=MAX_ACK_RECV_PER_LOOP;
|
||||
|
||||
const unsigned int MAX_RESEND_TIMES=5;
|
||||
const unsigned int DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_USEC=500*1000;
|
||||
const time_tick_t DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_TICK=DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_USEC/TIME_TICK_STEP_USEC;
|
||||
const unsigned int TIMEOUT_RELIABLE_SEND_MULTIPLE[MAX_RESEND_TIMES]={1,1,1,1,1};
|
||||
|
||||
const time_tick_t RESEND_PERSIST_INTERVAL=DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_USEC*TIMEOUT_RELIABLE_SEND_MULTIPLE[MAX_RESEND_TIMES-1];
|
||||
const time_tick_t FORCE_EST_INTERVAL=RESEND_PERSIST_INTERVAL*2*MAX_RESEND_TIMES;
|
||||
|
||||
const time_tick_t DEFAULT_STREAM_FROZEN_TICK_INTERVAL=30*1000*1000/TIME_TICK_STEP_USEC;
|
||||
|
||||
const unsigned int TIMEOUT_SMOOTH_STREAM_USEC=10*60*1000*1000; // 10min
|
||||
const unsigned int TIMEOUT_SEND_STREAM_USEC=9*60*1000*1000; // 9min,a little less than TIMEOUT_SMOOTH_STREAM_USEC
|
||||
const unsigned int TIMEOUT_RECV_STREAM_USEC=TIMEOUT_SMOOTH_STREAM_USEC+TIMEOUT_RELIABLE_SEND_MULTIPLE[MAX_RESEND_TIMES-1]*DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_USEC*MAX_RESEND_TIMES;
|
||||
|
||||
//TIMEOUT_SMOOTH_BLOCK_USEC+ACK_COMULATE_USEC<TIMEOUT_RELIABLE_SEND_BASE_USEC
|
||||
const unsigned int DEFAULT_TIMEOUT_SMOOTH_BLOCK_USEC=10*1000;
|
||||
const unsigned int DEFAULT_COMULATE_ACK_NUM=5;
|
||||
const unsigned int DEFAULT_ACK_COMULATE_USEC=100*1000;
|
||||
const unsigned int DEFALUT_SEND_WINDOW_SIZE=30;
|
||||
const unsigned int DEFALUT_RECV_WINDOW_SIZE=DEFALUT_SEND_WINDOW_SIZE;
|
||||
|
||||
#endif /*_BUSINESSMAN_LIMIT_INCLUDE_H_*/
|
||||
|
||||
16
src/support/Businessman/businessman_lock.h
Normal file
16
src/support/Businessman/businessman_lock.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _BIZMAN_LOCK_H_INCLUDE_
|
||||
#define _BIZMAN_LOCK_H_INCLUDE_
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t bizman_lock_t;
|
||||
|
||||
#define bizman_init_lock(lock) pthread_mutex_init(lock, NULL)
|
||||
#define bizman_lock(lock) pthread_mutex_lock(lock)
|
||||
#define bizman_unlock(lock) pthread_mutex_unlock(lock)
|
||||
#define bizman_trylock(lock) pthread_mutex_trylock(lock)
|
||||
|
||||
typedef pthread_cond_t bizman_cond_t;
|
||||
#define bizman_init_cond(cond) pthread_cond_init(cond,NULL)
|
||||
#define bizman_cond_wait(cond,lock) pthread_cond_wait(cond,lock)
|
||||
#define bizman_cond_timedwait(cond,lock,time) pthread_cond_timedwait(cond,lock,time)
|
||||
#define bizman_cond_signal(cond) pthread_cond_signal(cond)
|
||||
#endif //_BIZMAN_LOCK_H_INCLUDE_
|
||||
5
src/support/Businessman/businessman_memory.h
Normal file
5
src/support/Businessman/businessman_memory.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifndef _BIZMAN_MEMORY_INCLUDE_H_
|
||||
#define _BIZMAN_MEMORY_INCLUDE_H_
|
||||
#include<stdlib.h>
|
||||
#define b_malloc(s) calloc(1,s)
|
||||
#endif
|
||||
63
src/support/Businessman/businessman_packet.cpp
Normal file
63
src/support/Businessman/businessman_packet.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_packet.h"
|
||||
void init_packet(bizman_packet_t *p_pkt,char is_reliable,uint32 stream_id,int pkt_len)
|
||||
{
|
||||
if(is_reliable==TRUE)
|
||||
{
|
||||
p_pkt->flags|=FLAG_NEED_ACK;
|
||||
}
|
||||
p_pkt->id=stream_id;
|
||||
p_pkt->len=pkt_len;
|
||||
p_pkt->magic_num=PACKET_MAGIC_NUM;
|
||||
p_pkt->slice_num=0;
|
||||
}
|
||||
int is_bizman_packet(bizman_packet_t *p_pkt)
|
||||
{
|
||||
int i=0,user_data_len=0;
|
||||
bizman_slice_t* slice=NULL;
|
||||
if(p_pkt->magic_num!=PACKET_MAGIC_NUM)
|
||||
return FALSE;
|
||||
if(p_pkt->len>MTU_SIZE)
|
||||
return FALSE;
|
||||
slice=(bizman_slice_t*)((char*)p_pkt+LOAD_HEADER_LEN);
|
||||
for(i=0;i<p_pkt->slice_num;i++)
|
||||
{
|
||||
if(slice->slice_len>p_pkt->len-LOAD_HEADER_LEN-user_data_len-i*SLICE_HEADER_LEN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
user_data_len+=slice->slice_len-SLICE_HEADER_LEN;
|
||||
slice=(bizman_slice_t* )((char*)slice+slice->slice_len);
|
||||
}
|
||||
if(user_data_len+LOAD_HEADER_LEN+p_pkt->slice_num*SLICE_HEADER_LEN!=p_pkt->len)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
void set_packet_flag_last(bizman_packet_t* p_pkt)
|
||||
{
|
||||
p_pkt->flags|=FLAG_LAST_PKT;
|
||||
}
|
||||
void set_packet_flag_need_ack(bizman_packet_t* p_pkt)
|
||||
{
|
||||
p_pkt->flags|=FLAG_NEED_ACK;
|
||||
}
|
||||
send_data_refer_t* create_send_data_refer(char*data,int len,int dest_num)
|
||||
{
|
||||
send_data_refer_t* refer=NULL;
|
||||
refer=(send_data_refer_t*)b_malloc(sizeof(send_data_refer_t));
|
||||
refer->packet=(bizman_packet_t*)data;
|
||||
refer->data_len=len;
|
||||
refer->left_quote_count=dest_num;
|
||||
return refer;
|
||||
}
|
||||
void free_refer_and_data(send_data_refer_t* refer)
|
||||
{
|
||||
refer->left_quote_count--;
|
||||
if(refer->left_quote_count==0)
|
||||
{
|
||||
free(refer->packet);
|
||||
free(refer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
68
src/support/Businessman/businessman_packet.h
Normal file
68
src/support/Businessman/businessman_packet.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef _BIZMAN_PACKET_INCLUDE_H_
|
||||
#define _BIZMAN_PACKET_INCLUDE_H_
|
||||
#include "list.h"
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned short int uint16;
|
||||
typedef unsigned char uint8;
|
||||
const int MTU_SIZE=1472;
|
||||
const uint32 START_SEQ_NUM=1;
|
||||
const uint8 FLAG_NEED_ACK=0x01;
|
||||
const uint8 FLAG_LAST_PKT=0x02;
|
||||
const uint8 FLAG_ACK_PKT=0x04;
|
||||
const uint8 FLAG_FIN_STREAM=0x08;
|
||||
const uint8 FLAG_EST_STREAM=0x10;
|
||||
|
||||
const uint8 SLICE_LAST_FRAG=0x01;
|
||||
const uint32 PACKET_MAGIC_NUM=0x132B5FC;
|
||||
typedef struct _businessman_load_header{
|
||||
uint32 magic_num;
|
||||
uint32 id; //identify the stream
|
||||
#ifdef DEPLOY_YSP_SYSTEM
|
||||
char app_id[8];
|
||||
#endif
|
||||
uint32 sequence; //
|
||||
uint16 len; //including this header
|
||||
uint8 slice_num; //255 at most
|
||||
uint8 flags; //LAST NEEDACK
|
||||
}__attribute__((packed))bizman_packet_t;//24B
|
||||
typedef struct _businessman_slice_header{
|
||||
uint16 slice_len; //including this header
|
||||
uint8 flags;
|
||||
uint8 reserved;
|
||||
}bizman_slice_t;//4B
|
||||
typedef struct _businessman_wrap
|
||||
{
|
||||
unsigned int src_ip;
|
||||
unsigned int dest_ip;
|
||||
unsigned short src_port;
|
||||
unsigned short dest_port;
|
||||
}bizman_wrap_t;
|
||||
typedef struct _bizman_reliable_send_task_t
|
||||
{
|
||||
uint32 dest_ip;
|
||||
uint16 dest_port;
|
||||
bizman_packet_t* data;
|
||||
int len;
|
||||
}bizman_packet_send_task_t;
|
||||
typedef struct _businessman_send_data_refer_t{
|
||||
uint32 data_len;
|
||||
uint32 left_quote_count;
|
||||
bizman_packet_t* packet;
|
||||
}send_data_refer_t;
|
||||
typedef struct _businessman_send_data_index_t{
|
||||
list_index_t hook;
|
||||
send_data_refer_t* refer_index;
|
||||
}send_data_index_t;
|
||||
const unsigned int LOAD_HEADER_LEN=sizeof(bizman_packet_t);
|
||||
const unsigned int SLICE_HEADER_LEN=sizeof(bizman_slice_t);
|
||||
const unsigned int HEADER_RESERVED_LEN=LOAD_HEADER_LEN+SLICE_HEADER_LEN;
|
||||
const unsigned int LOAD_DAT_LEN=MTU_SIZE-HEADER_RESERVED_LEN;
|
||||
void init_packet(bizman_packet_t *p_pkt,char is_reliable,uint32 stream_id,int pkt_len);
|
||||
int is_bizman_packet(bizman_packet_t *p_pkt);
|
||||
void set_packet_flag_last(bizman_packet_t* p_pkt);
|
||||
void set_packet_flag_need_ack(bizman_packet_t* p_pkt);
|
||||
void free_refer_and_data(send_data_refer_t* refer);
|
||||
send_data_refer_t* create_send_data_refer(char*data,int len,int dest_num);
|
||||
#endif /*end _BIZMAN_PACKET_INCLUDE_H_*/
|
||||
|
||||
33
src/support/Businessman/businessman_time.cpp
Normal file
33
src/support/Businessman/businessman_time.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
//#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>//gettimeofday
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_limit.h"
|
||||
|
||||
static volatile unsigned int g_stream_id;//iatomic.h do not support atomic_inc_return operation in X86_64 platform
|
||||
|
||||
static struct timeval start_tv;
|
||||
int initial_ok=FALSE;
|
||||
time_tick_t get_time_tick(){
|
||||
struct timeval current_tv;
|
||||
time_tick_t ticks=0;
|
||||
gettimeofday(¤t_tv,NULL);
|
||||
ticks=(1000000*(current_tv.tv_sec-start_tv.tv_sec)+(current_tv.tv_usec-start_tv.tv_usec))/TIME_TICK_STEP_USEC;
|
||||
return ticks;
|
||||
}
|
||||
unsigned int generate_stream_id()
|
||||
{
|
||||
return g_stream_id++;
|
||||
}
|
||||
void bizman_timer_start(){
|
||||
if(initial_ok==FALSE)
|
||||
{
|
||||
gettimeofday(&start_tv,NULL);
|
||||
initial_ok=TRUE;
|
||||
g_stream_id=1;
|
||||
}
|
||||
}
|
||||
|
||||
12
src/support/Businessman/businessman_time.h
Normal file
12
src/support/Businessman/businessman_time.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* Businessman Data Exchange System Timer implement
|
||||
* if the user app initialed multi bizman_handler ,they will share a same timer.
|
||||
*/
|
||||
#ifndef _BIZMAN_TIME_INCLUDE_H_
|
||||
#define _BIZMAN_TIME_INCLUDE_H_
|
||||
const int TIME_TICK_STEP_USEC=100;//microsecond for time accuracy
|
||||
typedef unsigned long long time_tick_t;
|
||||
//typedef unsigned int time_tick_t;
|
||||
time_tick_t get_time_tick();
|
||||
void bizman_timer_start();
|
||||
unsigned int generate_stream_id();
|
||||
#endif //_BIZMAN_TIME_INCLUDE_H_
|
||||
267
src/support/Businessman/hash.cpp
Normal file
267
src/support/Businessman/hash.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
#include "hash.h"
|
||||
|
||||
/*
|
||||
* hash implementation, xh, 2001-07-26
|
||||
*/
|
||||
/*Developer Notice:
|
||||
in _bizman_kernel_hash_add function,hash table MALLOC memory for keys and RECORD data pointer,
|
||||
which means need NOT malloc memory for keys before call _bizman_kernel_hash_add. zhengchao
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* allocates memory for table.
|
||||
* returns:
|
||||
* -1, if memory fails.
|
||||
* -2, if parameters not acceptable.
|
||||
* 0, success;
|
||||
*
|
||||
* size is 2^N, mandatory or not?
|
||||
*/
|
||||
int _bizman_kernel_hash_create(hash_tab_t * table, uint size,
|
||||
key_comp_t * key_comp, key2index_t * key2index,
|
||||
int (* data_expire)(void *), void (* data_free)(void *))
|
||||
{
|
||||
uint s;
|
||||
|
||||
for(s = size; s != 0; ) {
|
||||
if(0x01 != s && 0x01 == (0x01 & s)) return -2;
|
||||
s = s >> 1;
|
||||
}
|
||||
table->elems = (hash_elem_t**)malloc(sizeof(hash_elem_t *) * size);
|
||||
if(NULL == table->elems)
|
||||
return -1;
|
||||
memset(table->elems, 0, sizeof(hash_elem_t *) * size);
|
||||
table->size = size;
|
||||
if(NULL == key_comp) table->key_comp = _bizman_kernel_hash_key_comp;
|
||||
else table->key_comp = key_comp;
|
||||
if(NULL == key2index) table->key2index = _bizman_kernel_hash_key2index;
|
||||
else table->key2index = key2index;
|
||||
table->expire = data_expire;
|
||||
table->free = data_free;
|
||||
table->elem_count = 0;
|
||||
table->threshold_lo = 0;
|
||||
table->threshold_hi = size;
|
||||
table->max_collision=0;
|
||||
table->avg_collision=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* frees table->elems and chains attached to each element of it.
|
||||
* always returns 0.
|
||||
*/
|
||||
int _bizman_kernel_hash_destroy(hash_tab_t * table, void (* func)(void *))
|
||||
{
|
||||
int i;
|
||||
hash_elem_t * cur;
|
||||
|
||||
for(i = 0; i < (int)table->size; i ++) {
|
||||
while(NULL != table->elems[i]) {
|
||||
cur = table->elems[i];
|
||||
if(NULL != func) func(cur->data);
|
||||
else if(NULL != table->free) table->free(cur->data);
|
||||
table->elems[i] = (table->elems[i])->next;
|
||||
free(cur->key);
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
free(table->elems);
|
||||
table->elems = NULL;
|
||||
table->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* adds data identified by key to table.
|
||||
* table->elems always points to the newest added element.
|
||||
* no two elements should have a same key, although them may have a same index.
|
||||
* returns:
|
||||
* -1, if duplicate is found;
|
||||
* -2, if memory fails;
|
||||
* 0, success.
|
||||
*/
|
||||
int _bizman_kernel_hash_add(hash_tab_t * table, uchar * key, uint size, void * data)
|
||||
{
|
||||
uint index;
|
||||
hash_elem_t * ptr;
|
||||
|
||||
index = table->key2index(table, key, size);
|
||||
for(ptr = table->elems[index]; NULL != ptr; ptr = ptr->next) {
|
||||
if(!table->key_comp(ptr->key, ptr->size, key, size))
|
||||
return -1;
|
||||
}
|
||||
if(NULL == (ptr = (hash_elem_t*)malloc(sizeof(hash_elem_t)))) return -2;
|
||||
if(NULL == (ptr->key = (unsigned char*)malloc(size))) {
|
||||
free(ptr);
|
||||
return -2;
|
||||
}
|
||||
memcpy(ptr->key, key, size);
|
||||
ptr->size = size;
|
||||
ptr->data = data;
|
||||
ptr->prev = NULL;
|
||||
ptr->next = table->elems[index];
|
||||
if(NULL != table->elems[index]) table->elems[index]->prev = ptr;
|
||||
table->elems[index] = ptr;
|
||||
table->elem_count ++;
|
||||
/*
|
||||
* scan table to find expired items when elem_count reaches threshold.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* deletes element identified by key from table.
|
||||
* returns:
|
||||
* -1, if not found;
|
||||
* 0, success.
|
||||
*/
|
||||
int _bizman_kernel_hash_del(hash_tab_t * table, uchar * key, uint size, void (* func)(void *))
|
||||
{
|
||||
uint index;
|
||||
hash_elem_t * ptr;
|
||||
|
||||
index = table->key2index(table, key, size);
|
||||
for(ptr = table->elems[index]; NULL != ptr; ptr = ptr->next) {
|
||||
if(!table->key_comp(ptr->key, ptr->size, key, size))
|
||||
break;
|
||||
}
|
||||
if(NULL == ptr) return 0; /* success, maybe? */
|
||||
if(NULL != ptr->prev) ptr->prev->next = ptr->next;
|
||||
else table->elems[index] = ptr->next;
|
||||
if(NULL != ptr->next) ptr->next->prev = ptr->prev;
|
||||
if(NULL != func) func(ptr->data);
|
||||
else if(NULL != table->free) table->free(ptr->data);
|
||||
free(ptr->key);
|
||||
free(ptr);
|
||||
table->elem_count --;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns data associated with key in table;
|
||||
* not found, returns NULL.
|
||||
*/
|
||||
void * _bizman_kernel_hash_sel(hash_tab_t * table, uchar * key, uint size)
|
||||
{
|
||||
uint index;
|
||||
hash_elem_t * ptr;
|
||||
uint i=0;
|
||||
index = table->key2index(table, key, size);
|
||||
for(ptr = table->elems[index]; NULL != ptr; ptr = ptr->next) {
|
||||
i++;
|
||||
if(!table->key_comp(ptr->key, ptr->size, key, size))
|
||||
break;
|
||||
}
|
||||
if(i>table->max_collision)
|
||||
{
|
||||
table->max_collision=i;
|
||||
}
|
||||
if(NULL != ptr) return ptr->data;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns hash index of key.
|
||||
* never fails.
|
||||
*/
|
||||
uint _bizman_kernel_hash_key2index(hash_tab_t * table, uchar * key, uint size)
|
||||
{
|
||||
uchar * c;
|
||||
uint h, g;
|
||||
if(size==4) return *(unsigned int*)key%table->size;
|
||||
for (c = key, h = 0; c - key < size; c ++) {
|
||||
h = (h << 2) + c[0];
|
||||
if(0 != (g = (h & 0xf0000000))) {
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
return h % table->size;
|
||||
}
|
||||
|
||||
int _bizman_kernel_hash_key_comp(uchar * key1, uint size1, uchar * key2, uint size2)
|
||||
{
|
||||
if(size1 != size2) return 1;
|
||||
if(size1==4)
|
||||
{
|
||||
if(*(int*)key1==*(int*)key2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return memcmp(key1, key2, size1);
|
||||
}
|
||||
|
||||
int _bizman_kernel_hash_iterate(hash_tab_t * table, void (* func)(uchar * key, uint size, void * data))
|
||||
{
|
||||
int i;
|
||||
hash_elem_t * ptr;
|
||||
|
||||
if(NULL == func) return 0;
|
||||
for(i = 0; i < (int)table->size; i ++) {
|
||||
for(ptr = table->elems[i]; NULL != ptr; ptr = ptr->next)
|
||||
func(ptr->key, ptr->size, ptr->data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _bizman_kernel_hash_iterate2(hash_tab_t * table, void (* func)(uchar * key, uint size, void * data, void * u), void * user)
|
||||
{
|
||||
int i;
|
||||
hash_elem_t * ptr;
|
||||
|
||||
if(NULL == func) return 0;
|
||||
for(i = 0; i < (int)table->size; i ++) {
|
||||
for(ptr = table->elems[i]; NULL != ptr; ptr = ptr->next)
|
||||
func(ptr->key, ptr->size, ptr->data, user);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _bizman_kernel_hash_expire(hash_tab_t * table)
|
||||
{
|
||||
int i, delta;
|
||||
hash_elem_t * ptr, * tmp;
|
||||
|
||||
if(NULL == table->expire) return 0;
|
||||
for(i = 0; i < (int)table->size; i ++) {
|
||||
ptr = table->elems[i];
|
||||
while(NULL != ptr) {
|
||||
if(table->expire(ptr->data)) {
|
||||
if(NULL != ptr->prev)
|
||||
ptr->prev->next = ptr->next;
|
||||
else table->elems[i] = ptr->next;
|
||||
if(NULL != ptr->next)
|
||||
ptr->next->prev = ptr->prev;
|
||||
tmp = ptr;
|
||||
ptr = ptr->next;
|
||||
if(NULL != table->free)
|
||||
table->free(tmp->data);
|
||||
free(tmp);
|
||||
|
||||
table->elem_count --;
|
||||
if(table->elem_count < table->threshold_lo) {
|
||||
delta = table->threshold_hi - table->threshold_lo;
|
||||
delta = delta << 1;
|
||||
if(delta > HASH_THRESHOLD_MAX_DELTA)
|
||||
delta = HASH_THRESHOLD_MAX_DELTA;
|
||||
table->threshold_hi = table->threshold_lo;
|
||||
if(table->threshold_lo > (unsigned int)delta)
|
||||
table->threshold_lo -= delta;
|
||||
else
|
||||
table->threshold_lo = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
211
src/support/Businessman/hash.h
Normal file
211
src/support/Businessman/hash.h
Normal file
@@ -0,0 +1,211 @@
|
||||
#ifndef _LIB_HASH_H_INCLUDED_
|
||||
#define _LIB_HASH_H_INCLUDED_
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/*
|
||||
* general purpose hash table implementation.
|
||||
*
|
||||
* xiang hong
|
||||
* 2002-07-28
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#ifndef uint
|
||||
#define uint unsigned int
|
||||
#endif
|
||||
|
||||
#define HASH_THRESHOLD_MAX 65536
|
||||
#define HASH_THRESHOLD_MIN 0
|
||||
#define HASH_THRESHOLD_MAX_DELTA 32768
|
||||
#define HASH_THRESHOLD_MIN_DELTA 16
|
||||
|
||||
struct __hash_tab;
|
||||
|
||||
/*
|
||||
* hash key compare function prototype, see _bizman_kernel_hash_key_comp().
|
||||
*/
|
||||
typedef int key_comp_t(uchar * key1, uint size1, uchar * key2, uint size2);
|
||||
|
||||
/*
|
||||
* hash key->index computing function prototype, see _bizman_kernel_hash_key2index().
|
||||
*/
|
||||
typedef uint key2index_t(struct __hash_tab * tab, uchar * key, uint size);
|
||||
|
||||
/*
|
||||
* hash element structure.
|
||||
*
|
||||
* key: a copy of key;
|
||||
* size: size of key;
|
||||
* data: pointer to attached data;
|
||||
* prev, next: pointer to prev and next item;
|
||||
*/
|
||||
typedef struct struct_hash_elem {
|
||||
uchar * key;
|
||||
uint size;
|
||||
void * data;
|
||||
struct struct_hash_elem * prev;
|
||||
struct struct_hash_elem * next;
|
||||
} hash_elem_t;
|
||||
|
||||
/*
|
||||
* hash structure.
|
||||
*
|
||||
* size: number of slots;
|
||||
* key_comp: pointer to the function that compares 2 keys;
|
||||
* key2index: pointer to the function that computes index from key;
|
||||
* expire: pointer to the function that checks if attached data is expired;
|
||||
* free: pointer to the function that cleans up attached data;
|
||||
* elems: array of slots;
|
||||
* elem_count: number of items;
|
||||
* threshold_lo, threshold_hi: low and high threshold; when elem_count reaches
|
||||
* one of them, an iteration will be launched to clean up expired items;
|
||||
*/
|
||||
typedef struct __hash_tab {
|
||||
uint size;
|
||||
key_comp_t * key_comp;
|
||||
key2index_t * key2index;
|
||||
int (* expire)(void * data);
|
||||
void (* free)(void * data);
|
||||
hash_elem_t ** elems;
|
||||
uint elem_count;
|
||||
uint threshold_lo;
|
||||
uint threshold_hi;
|
||||
uint max_collision;
|
||||
uint avg_collision;
|
||||
} hash_tab_t;
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_create
|
||||
* functionality: allocats memory for hash slots, and fill in hash structure;
|
||||
* param:
|
||||
* table: caller allocated hash table structure, gets filled in;
|
||||
* size: how big do you want the table to be;
|
||||
* key_comp, key2index, data_expire, data_free: function pointers, can be
|
||||
* NULL;
|
||||
* returns:
|
||||
* 0, success;
|
||||
* -1, memory failure;
|
||||
* -2, parameter not acceptable;
|
||||
*/
|
||||
int _bizman_kernel_hash_create(hash_tab_t * table, uint size,
|
||||
key_comp_t * key_comp, key2index_t * key2index,
|
||||
int (* data_expire)(void *), void (* data_free)(void *));
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_destroy
|
||||
* functionality: cleans up hash structure, frees memory occupied;
|
||||
* param:
|
||||
* table: who is the victim;
|
||||
* func: callback function to clean up data attached to hash items;
|
||||
* returns:
|
||||
* always returns 0;
|
||||
*/
|
||||
int _bizman_kernel_hash_destroy(hash_tab_t * table, void (* func)(void *));
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_add
|
||||
* functionality: adds item to table, call _bizman_kernel_hash_expire() if elem_count gets
|
||||
* bigger than threshold_hi, and adjust threshold;
|
||||
* param:
|
||||
* table: to which table do you want to add;
|
||||
* key: what is the label;
|
||||
* size: how long is the label;
|
||||
* data: what data do you want to attach;
|
||||
* returns:
|
||||
* 0, success;
|
||||
* -1, duplicates found and can't add this one;
|
||||
* -2, memory failure;
|
||||
*/
|
||||
int _bizman_kernel_hash_add(hash_tab_t * table, uchar * key, uint size, void * data);
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_del
|
||||
* functionality: deletes item from table, call _bizman_kernel_hash_expire() if elem_count
|
||||
* gets smaller than threshold_lo, and adjust threshold;
|
||||
* param:
|
||||
* table: from which table do you want to delete;
|
||||
* key: what is the label;
|
||||
* size: how long is the label;
|
||||
* func: callback function to clean up data attached to hash items;
|
||||
* returns:
|
||||
* 0, success;
|
||||
* -1, no such thing;
|
||||
*/
|
||||
int _bizman_kernel_hash_del(hash_tab_t * table, uchar * key, uint size, void (* func)(void *));
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_sel
|
||||
* functionality: selects item from table;
|
||||
* param:
|
||||
* table: from which table do you want to select;
|
||||
* key: what is the label;
|
||||
* size: how long is the label;
|
||||
* returns:
|
||||
* pointer to attached data;
|
||||
* NULL if not found; (thus be careful if you are attaching NULL data on
|
||||
* purpose.)
|
||||
*/
|
||||
void * _bizman_kernel_hash_sel(hash_tab_t * table, uchar * key, uint size);
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_iterate
|
||||
* functionality: iterates each hash item;
|
||||
* params:
|
||||
* table: what table is to be iterated;
|
||||
* func: what do you want to do to each attached data item;
|
||||
* returns:
|
||||
* always 0;
|
||||
*/
|
||||
int _bizman_kernel_hash_iterate(hash_tab_t * table, void (* func)(uchar * key, uint size, void * data));
|
||||
int _bizman_kernel_hash_iterate2(hash_tab_t * table, void (* func)(uchar * key, uint size, void * data, void * u), void * user);
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_expire
|
||||
* functionality: iterates each item and deletes those that are expired;
|
||||
* params:
|
||||
* table: what table do you want to check;
|
||||
* returns:
|
||||
* always 0;
|
||||
*/
|
||||
int _bizman_kernel_hash_expire(hash_tab_t * table);
|
||||
|
||||
/*
|
||||
* name: _bizman_kernel_hash_key2index
|
||||
* functionality: computes index from key, default key2index implementation
|
||||
* if previous _bizman_kernel_hash_create() call did not provide such a function;
|
||||
* params:
|
||||
* table: with which table are you dealing, we want this param be present
|
||||
* because we may need size of table to compute the key;
|
||||
* key: what is the label;
|
||||
* size: how long is the label;
|
||||
* returns:
|
||||
* index in given table for given key, never fails;
|
||||
*/
|
||||
uint _bizman_kernel_hash_key2index(hash_tab_t * table, uchar * key, uint size);
|
||||
|
||||
/*
|
||||
* name: hash_comp
|
||||
* functionality: compares two key;
|
||||
* params:
|
||||
* key1, key2: what are the labels;
|
||||
* size1, size2: how long are them;
|
||||
* returns:
|
||||
* 0, if two keys are identical; (just a simple memcmp() );
|
||||
* 1, no.
|
||||
*/
|
||||
int _bizman_kernel_hash_key_comp(uchar * key1, uint size1, uchar * key2, uint size2);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_HASH_H_INCLUDED_ */
|
||||
|
||||
|
||||
BIN
src/support/Businessman/libbusinessman.a
Normal file
BIN
src/support/Businessman/libbusinessman.a
Normal file
Binary file not shown.
BIN
src/support/Businessman/libbusinessman.so
Normal file
BIN
src/support/Businessman/libbusinessman.so
Normal file
Binary file not shown.
369
src/support/Businessman/list.cpp
Normal file
369
src/support/Businessman/list.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
|
||||
/*list.cpp
|
||||
* extract from linux kernel
|
||||
* zhengchao add list integrity check function
|
||||
* for list control
|
||||
*/
|
||||
|
||||
#include "list.h"
|
||||
list_index_t *q_read_head(queue_head_t *qhead_obj)
|
||||
{
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=NULL;
|
||||
|
||||
if(NULL == qhead->head)
|
||||
return p;
|
||||
p = qhead->head;
|
||||
return p;
|
||||
}
|
||||
|
||||
// return a ~NULL pointer of list_item_t for success
|
||||
list_index_t *q_get_head(queue_head_t *qhead_obj)
|
||||
{
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=NULL;
|
||||
|
||||
if(NULL == qhead->head)
|
||||
return p;
|
||||
p = qhead->head;
|
||||
if(qhead->head == qhead->tail) {
|
||||
qhead->head = qhead->tail = NULL;
|
||||
qhead->listcount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
qhead->head = p->nextele;
|
||||
p->nextele->preele = NULL;
|
||||
qhead->listcount--;
|
||||
}
|
||||
p->nextele = NULL;
|
||||
p->preele=NULL;
|
||||
#ifdef BIZMAN_DEBUG_LIST
|
||||
int check_result=q_list_check(qhead_obj,NULL);
|
||||
if(check_result<0)
|
||||
{
|
||||
fprintf(stderr,"Queue Check Error:%d.\n",check_result);
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
// return a ~NULL pointer of list_item_t for success
|
||||
list_index_t *q_get_tail(queue_head_t *qhead_obj)
|
||||
{
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=NULL;
|
||||
|
||||
if(NULL == qhead->tail)
|
||||
return p;
|
||||
p = qhead->tail;
|
||||
if(qhead->head == qhead->tail) {
|
||||
qhead->head = qhead->tail = NULL;
|
||||
qhead->listcount = 0;
|
||||
return p;
|
||||
}
|
||||
qhead->tail = p->preele;
|
||||
p->preele->nextele = NULL;
|
||||
p->preele = NULL;
|
||||
|
||||
qhead->listcount--;
|
||||
return p;
|
||||
}
|
||||
|
||||
// always success
|
||||
list_index_t *q_join_tail(queue_head_t *qhead_obj, list_index_t *lindex_obj)
|
||||
{
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=lindex_obj;
|
||||
|
||||
if(NULL == p)
|
||||
return p;
|
||||
p->nextele = p->preele = NULL;
|
||||
if(NULL == qhead->tail) {
|
||||
qhead->head = qhead->tail = p;
|
||||
qhead_obj->listcount = 1;
|
||||
return p;
|
||||
}
|
||||
p->preele = qhead->tail;
|
||||
qhead->tail->nextele = p;
|
||||
qhead->tail = p;
|
||||
|
||||
qhead->listcount++;
|
||||
#ifdef BIZMAN_DEBUG_LIST
|
||||
int check_result=q_list_check(qhead_obj,NULL);
|
||||
if(check_result<0)
|
||||
{
|
||||
fprintf(stderr,"Queue Check Error:%d.\n",check_result);
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
// always success
|
||||
list_index_t *q_join_head(queue_head_t *qhead_obj, list_index_t *lindex_obj)
|
||||
{
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=lindex_obj;
|
||||
|
||||
if(NULL == p)
|
||||
return p;
|
||||
p->nextele = p->preele = NULL;
|
||||
if(NULL == qhead->head) {
|
||||
qhead->head = qhead->tail = p;
|
||||
qhead->listcount = 1;
|
||||
return p;
|
||||
}
|
||||
p->nextele = qhead->head;
|
||||
qhead->head->preele = p;
|
||||
qhead->head = p;
|
||||
|
||||
qhead->listcount++;
|
||||
return p;
|
||||
}
|
||||
|
||||
list_index_t *q_leave_list(queue_head_t *qhead_obj, list_index_t *lindex_obj)
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG_LIST
|
||||
if(0>q_is_item_in_list_quick(qhead_obj,lindex_obj))
|
||||
{
|
||||
fprintf(stderr,"Obj not in Queue.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
queue_head_t *qhead=qhead_obj;
|
||||
list_index_t *p=NULL;
|
||||
|
||||
if(NULL == lindex_obj)
|
||||
return p;
|
||||
if(NULL == qhead->head)
|
||||
return p;
|
||||
|
||||
p = lindex_obj;
|
||||
if(NULL == p->preele && NULL == p->nextele) {//this action is damn danger!!!
|
||||
qhead->tail = qhead->head = NULL;
|
||||
qhead->listcount = 0;
|
||||
return p;
|
||||
}
|
||||
if(NULL == p->preele) {
|
||||
qhead->head = p->nextele;
|
||||
p->nextele->preele = NULL;
|
||||
p->nextele = NULL;
|
||||
qhead->listcount--;
|
||||
return p;
|
||||
}
|
||||
|
||||
if(NULL == p->nextele) {
|
||||
qhead->tail = p->preele;
|
||||
p->preele->nextele = NULL;
|
||||
p->preele = NULL;
|
||||
qhead->listcount--;
|
||||
return p;
|
||||
}
|
||||
|
||||
p->nextele->preele = p->preele;
|
||||
p->preele->nextele = p->nextele;
|
||||
p->nextele = p->preele = NULL;
|
||||
qhead->listcount--;
|
||||
#ifdef BIZMAN_DEBUG_LIST
|
||||
int check_result=q_list_check(qhead_obj,NULL);
|
||||
if(check_result<0)
|
||||
{
|
||||
fprintf(stderr,"Queue Check Error:%d.\n",check_result);
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
list_index_t *q_join_list_n(queue_head_t *qhead_obj, list_index_t *lobj_next, list_index_t *lindex_obj)
|
||||
{
|
||||
list_index_t *p=lindex_obj, *next=lobj_next;
|
||||
queue_head_t *pq=qhead_obj;
|
||||
|
||||
if(NULL == p)
|
||||
return p;
|
||||
|
||||
if(NULL == next) {
|
||||
q_join_tail(pq, p);
|
||||
return p;
|
||||
}
|
||||
else if(NULL == next->preele) {
|
||||
q_join_head(pq, p);
|
||||
}
|
||||
else {
|
||||
qhead_obj->listcount++;
|
||||
|
||||
p->nextele = next;
|
||||
p->preele = next->preele;
|
||||
|
||||
next->preele = p;
|
||||
p->preele->nextele = p;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
list_index_t *q_join_list_p(queue_head_t *qhead_obj, list_index_t *lobj_pre, list_index_t *lindex_obj)
|
||||
{
|
||||
list_index_t *p=lindex_obj, *pre=lobj_pre;
|
||||
queue_head_t *pq=qhead_obj;
|
||||
|
||||
if(NULL == p)
|
||||
return p;
|
||||
|
||||
if(NULL == pre) {
|
||||
q_join_head(pq, p);
|
||||
return p;
|
||||
}
|
||||
else if(NULL == pre->nextele) {
|
||||
q_join_tail(pq, p);
|
||||
}
|
||||
else {
|
||||
qhead_obj->listcount++;
|
||||
|
||||
p->preele = pre;
|
||||
p->nextele = pre->nextele;
|
||||
|
||||
pre->nextele = p;
|
||||
p->nextele->preele = p;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
/*Function:Check the intergrity of the list,to dectect memory mess.
|
||||
*Input: Queue Head,data check call back function
|
||||
*Output: return a number below zero,if the queue got a problem,else return 0;
|
||||
*Author:zhengchao@iie.ac.cn at 20100913
|
||||
*/
|
||||
int q_list_check(const queue_head_t *qhead_obj,int(*quiddity_check)(const void *)){
|
||||
// list_index_t *p=NULL, *pre=NULL;
|
||||
// int linked_ele_number=0;
|
||||
int ret=0;
|
||||
// return 0;
|
||||
if(qhead_obj->listcount==0)
|
||||
{
|
||||
if(qhead_obj->head!=NULL||qhead_obj->head!=NULL)
|
||||
{
|
||||
ret=-1;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(qhead_obj->head==NULL||qhead_obj->tail==NULL)
|
||||
{
|
||||
ret=-2;
|
||||
goto exit;
|
||||
}
|
||||
if(qhead_obj->listcount>1){
|
||||
if(qhead_obj->head->preele!=NULL||qhead_obj->head->nextele==NULL)
|
||||
{
|
||||
ret=-3;
|
||||
goto exit;
|
||||
}
|
||||
if(qhead_obj->tail->preele==NULL||qhead_obj->tail->nextele!=NULL)
|
||||
{
|
||||
ret=-4;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
/*
|
||||
pre=qhead_obj->head;
|
||||
p=pre->nextele;
|
||||
while(p!=NULL){
|
||||
linked_ele_number++;
|
||||
|
||||
//Is the declared size equal to element linked number;
|
||||
if(linked_ele_number > qhead_obj->listcount)
|
||||
{
|
||||
ret=-5;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
//Is element's preele pointer equal to its preele
|
||||
if(pre!=p->preele)
|
||||
{
|
||||
ret=-6;
|
||||
goto exit;
|
||||
}
|
||||
if(quiddity_check!=NULL){
|
||||
if(0>quiddity_check(p->quiddity))
|
||||
{
|
||||
ret =-7;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
pre=p;
|
||||
p=p->nextele;
|
||||
}
|
||||
//Is the last element equal to tail
|
||||
if(pre!=qhead_obj->tail)
|
||||
{
|
||||
ret=-8;
|
||||
goto exit;
|
||||
}
|
||||
if(linked_ele_number !=qhead_obj->listcount-1)
|
||||
{
|
||||
ret=-9;
|
||||
goto exit;
|
||||
}
|
||||
*/
|
||||
exit:
|
||||
if(ret<0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
/*Simple check,not raversal*/
|
||||
int q_is_item_in_list(queue_head_t *qhead_obj, list_index_t *lindex_obj){
|
||||
// list_index_t* pre=lindex_obj->preele;
|
||||
// list_index_t*next=lindex_obj->nextele;
|
||||
list_index_t*p=NULL;
|
||||
if(qhead_obj->listcount==0)
|
||||
return -1;
|
||||
if(lindex_obj->nextele==NULL&&lindex_obj->preele==NULL&&qhead_obj->listcount>1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int i=0;
|
||||
p=qhead_obj->head;
|
||||
for(i=0;i<qhead_obj->listcount;i++)
|
||||
{
|
||||
if(p==lindex_obj)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
p=p->nextele;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
/*every list_index_t leaves list,its pre and next will be set NULL
|
||||
* In Configuration Transmiiter project, not null element will consider in list,
|
||||
* pre and next is NULL only if there's one element in list only*/
|
||||
int q_is_item_in_list_quick(queue_head_t *qhead_obj, list_index_t *lindex_obj)
|
||||
{
|
||||
//empty list
|
||||
if(qhead_obj->listcount==0)
|
||||
return -1;
|
||||
//one element
|
||||
if(qhead_obj->listcount==1)
|
||||
{
|
||||
if(qhead_obj->head!=lindex_obj)
|
||||
return -1;
|
||||
}
|
||||
//have one more element
|
||||
if(qhead_obj->listcount>1)
|
||||
{
|
||||
if(lindex_obj->nextele==NULL&&lindex_obj->preele==NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
29
src/support/Businessman/list.h
Normal file
29
src/support/Businessman/list.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _LIST_H_INCLUDED
|
||||
#define _LIST_H_INCLUDED
|
||||
#include<stdio.h> //use NULL
|
||||
typedef struct list_index {
|
||||
struct list_index *nextele;
|
||||
struct list_index *preele;
|
||||
void *quiddity;
|
||||
}list_index_t;
|
||||
|
||||
typedef struct queue_head {
|
||||
list_index_t *head;
|
||||
list_index_t *tail;
|
||||
int listcount;
|
||||
}queue_head_t;
|
||||
|
||||
|
||||
list_index_t *q_get_head(queue_head_t *qhead_obj);
|
||||
list_index_t *q_get_tail(queue_head_t *qhead_obj);
|
||||
list_index_t *q_join_tail(queue_head_t *qhead_obj, list_index_t *lindex_obj);
|
||||
list_index_t *q_join_head(queue_head_t *qhead_obj, list_index_t *lindex_obj);
|
||||
list_index_t *q_leave_list(queue_head_t *qhead_obj, list_index_t *lindex_obj);
|
||||
list_index_t *q_join_list_n(queue_head_t *qhead_obj, list_index_t *lobj_next, list_index_t *lindex_obj);
|
||||
list_index_t *q_join_list_p(queue_head_t *qhead_obj, list_index_t *lobj_pre, list_index_t *lindex_obj);
|
||||
list_index_t *q_read_head(queue_head_t *qhead_obj);
|
||||
int q_list_check(const queue_head_t *qhead_obj,int(*quiddity_check)(const void *));
|
||||
int q_is_item_in_list(queue_head_t *qhead_obj, list_index_t *lindex_obj);
|
||||
int q_is_item_in_list_quick(queue_head_t *qhead_obj, list_index_t *lindex_obj);
|
||||
#endif /* _LIST_H_INCLUDED */
|
||||
|
||||
199
src/support/Businessman/network_layer.cpp
Normal file
199
src/support/Businessman/network_layer.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
#include <sys/socket.h>//socket
|
||||
#include <sys/types.h>//socket
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h> //strerror
|
||||
#include <errno.h>//strerror
|
||||
#include <fcntl.h>//fcntl
|
||||
#include <unistd.h>//fcntl
|
||||
#include <net/if.h>//fcntl
|
||||
#include <stdlib.h>//free
|
||||
#include <sys/ioctl.h>//ioctl
|
||||
#include "businessman_error.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_limit.h"
|
||||
#include "network_layer.h"
|
||||
|
||||
#ifdef DEPLOY_YSP_SYSTEM
|
||||
//this function defined in df_B feedback.c
|
||||
extern "C" int pag_send_av_udp(int Datasize, const char *pData, u_int src_ip, u_int dst_ip, u_short src_prt, u_short dst_prt);
|
||||
#endif
|
||||
void set_network_interface(network_space_t* network_layer, int interface_type,const char* interface_name){
|
||||
switch(interface_type)
|
||||
{
|
||||
case BIZMAN_INTERFACE_SOCKET:
|
||||
network_layer->socket_interface_name=(char*)b_malloc(strlen(interface_name)+1);
|
||||
memcpy(network_layer->socket_interface_name,interface_name,strlen(interface_name));
|
||||
break;
|
||||
#ifdef DEPLOY_YSP_SYSTEM
|
||||
case BIZMAN_INTERFACE_PAG:
|
||||
network_layer->using_pag_send=TRUE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
set_user_error("invalid interface type %d",interface_type);
|
||||
break;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
int set_network_listen_port(network_space_t* network_layer, unsigned short port)
|
||||
{
|
||||
network_layer->listen_port=port;
|
||||
return 0;
|
||||
}
|
||||
int set_network_send_port(network_space_t* network_layer, unsigned short port)
|
||||
{
|
||||
network_layer->send_port=port;
|
||||
return 0;
|
||||
}
|
||||
int startup_udp(network_space_t* network_layer)
|
||||
{
|
||||
unsigned short bind_port=network_layer->listen_port;
|
||||
int sd_udp=-1;
|
||||
int flags;
|
||||
struct ifreq ifr;
|
||||
|
||||
|
||||
|
||||
if(-1==(sd_udp = socket(AF_INET, SOCK_DGRAM, 0)))
|
||||
{
|
||||
set_user_error( "socket error: %d %s, restart socket.", errno, strerror(errno));
|
||||
sd_udp=-1;
|
||||
}
|
||||
if(NULL!=network_layer->socket_interface_name)
|
||||
{
|
||||
strcpy(ifr.ifr_name,network_layer->socket_interface_name);
|
||||
if (ioctl(sd_udp, SIOCGIFADDR, &ifr) < 0)
|
||||
{
|
||||
set_user_error( "get interface %s addr error",network_layer->socket_interface_name);
|
||||
return -1;
|
||||
}
|
||||
network_layer->src_addr = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr;
|
||||
}
|
||||
flags=fcntl(sd_udp,F_GETFL);
|
||||
flags|=O_NONBLOCK;
|
||||
if(fcntl(sd_udp,F_SETFL,flags)==-1)
|
||||
{
|
||||
set_user_error( "socket error: %d %s, restart socket.", errno, strerror(errno));
|
||||
sd_udp=-1;
|
||||
}
|
||||
int opt=1;
|
||||
struct sockaddr_in socket;
|
||||
memset(&socket, 0,sizeof(socket));
|
||||
socket.sin_family = AF_INET;
|
||||
socket.sin_port = htons(bind_port);
|
||||
socket.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (setsockopt (sd_udp, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt) ) < 0) {
|
||||
set_user_error("setsockopt error: %d %s, restart socket.", errno, strerror(errno));
|
||||
close (sd_udp);
|
||||
sd_udp=-1;
|
||||
return sd_udp;
|
||||
}
|
||||
if(-1 == bind(sd_udp, (struct sockaddr *)(&socket), sizeof(socket))) {
|
||||
set_user_error("bind error: %d %s, restart socket.", errno, strerror(errno));
|
||||
close (sd_udp);
|
||||
sd_udp=-1;
|
||||
return sd_udp;
|
||||
}
|
||||
return sd_udp;
|
||||
}
|
||||
int startup_pag_send(){
|
||||
return 1;
|
||||
}
|
||||
int init_network_layer(network_space_t* network_space)
|
||||
{
|
||||
if(TRUE==network_space->using_pag_send)
|
||||
{
|
||||
if(network_space->listen_port==0)
|
||||
{
|
||||
set_user_error("listen port is necessary in pag send");
|
||||
return -1;
|
||||
}
|
||||
if(NULL==network_space->socket_interface_name)
|
||||
{
|
||||
set_user_error("socket interface name is necessary in pag send");
|
||||
}
|
||||
}
|
||||
network_space->socket_handle=startup_udp(network_space);
|
||||
return 1;
|
||||
}
|
||||
network_space_t* get_network_handle(void)
|
||||
{
|
||||
return (network_space_t*)b_malloc(sizeof(network_space_t));
|
||||
}
|
||||
void destroy_network_handle(network_space_t* network_layer)
|
||||
{
|
||||
if(network_layer->socket_handle>0)
|
||||
{
|
||||
close(network_layer->socket_handle);
|
||||
}
|
||||
if(NULL!=network_layer->socket_interface_name)
|
||||
{
|
||||
free(network_layer->socket_interface_name);
|
||||
}
|
||||
free(network_layer);
|
||||
}
|
||||
int do_actual_send(network_space_t * network_handle, unsigned int dest_ip, unsigned short dest_port, const char * data, int len)
|
||||
{
|
||||
int to_send_len=len;
|
||||
int already_sended_len=0,this_sended_len=0;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr =dest_ip;
|
||||
addr.sin_port = htons(dest_port);
|
||||
|
||||
if(TRUE==network_handle->using_pag_send)
|
||||
{
|
||||
#ifdef DEPLOY_YSP_SYSTEM
|
||||
if(0>pag_send_av_udp(len,data, network_handle->src_addr, dest_ip,network_handle->listen_port,dest_port))
|
||||
{
|
||||
set_user_error("pag send error.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
while(to_send_len>already_sended_len)
|
||||
{
|
||||
this_sended_len=sendto(network_handle->socket_handle,(void*)(data+already_sended_len),
|
||||
to_send_len-already_sended_len,
|
||||
0,
|
||||
(struct sockaddr *)&(addr),
|
||||
sizeof(addr));
|
||||
if(this_sended_len==-1)
|
||||
{
|
||||
if((EAGAIN == errno)||( EINTR == errno )|| (EWOULDBLOCK==errno))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_user_error("at send,socket error: %d %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
already_sended_len=+this_sended_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int do_actual_recv(network_space_t *network_handle,unsigned int *src_ip,unsigned short* src_port,char*buf,int buf_len)
|
||||
{
|
||||
int received_length=-1;
|
||||
struct sockaddr_in src_socket;
|
||||
|
||||
int socket_length=sizeof(src_socket);
|
||||
received_length = recvfrom(network_handle->socket_handle, buf, buf_len, 0, (struct sockaddr *)&src_socket, (socklen_t*)(&socket_length));
|
||||
if(-1==received_length)
|
||||
{
|
||||
// set_user_error( "UDP rcv error %d, %s", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
*src_ip=src_socket.sin_addr.s_addr;
|
||||
*src_port=ntohs(src_socket.sin_port);
|
||||
}
|
||||
return received_length;
|
||||
}
|
||||
|
||||
30
src/support/Businessman/network_layer.h
Normal file
30
src/support/Businessman/network_layer.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _BIZMAN_NETWORK_H_INCLUDE_
|
||||
#define _BIZMAN_NETWORK_H_INCLUDE_
|
||||
#include "businessman_error.h"
|
||||
const int BIZMAN_INTERFACE_SOCKET=0;
|
||||
const int BIZMAN_INTERFACE_PAG=0xf;
|
||||
const int MAX_INTERFACE_NUM=2;
|
||||
typedef struct _businessman_netwrok_space{
|
||||
|
||||
char* socket_interface_name;
|
||||
unsigned int src_addr;
|
||||
unsigned char src_port;
|
||||
int using_pag_send;
|
||||
int socket_handle;
|
||||
unsigned short listen_port;
|
||||
unsigned short send_port;
|
||||
}network_space_t;
|
||||
|
||||
network_space_t* get_network_handle(void);
|
||||
void destroy_network_handle(network_space_t* network_layer);
|
||||
void set_network_interface(network_space_t* network_layer, int interface_type,const char* interface_name);
|
||||
int set_network_listen_port(network_space_t* network_layer, unsigned short port);
|
||||
int set_network_send_port(network_space_t* network_layer, unsigned short port);
|
||||
|
||||
/*return 0 when success,return -1 when failed*/
|
||||
int init_network_layer(network_space_t* network_space);
|
||||
|
||||
int do_actual_send(network_space_t *network_handle,unsigned int dest_ip,unsigned short dest_port,const char* data,int len);
|
||||
/*return received length(>=0) when success,return -1 when failed*/
|
||||
int do_actual_recv(network_space_t *network_handle,unsigned int *src_ip,unsigned short* src_port,char*buf,int buf_len);
|
||||
#endif //_BIZMAN_NETWORK_H_INCLUDE_
|
||||
655
src/support/Businessman/reliable_recv.cpp
Normal file
655
src/support/Businessman/reliable_recv.cpp
Normal file
@@ -0,0 +1,655 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>//memcpy
|
||||
#include <assert.h>
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_error.h"
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_lock.h"
|
||||
#include "bizman.h"
|
||||
#include "reliable_recv.h"
|
||||
|
||||
const unsigned int RELIABLE_STREAM_HASH_SIZE=1024*8;
|
||||
|
||||
const time_tick_t TIMEOUT_RECV_STREAM_TICK=TIMEOUT_RECV_STREAM_USEC/TIME_TICK_STEP_USEC;
|
||||
const time_tick_t DEFAULT_ACK_COMULATE_TICK=DEFAULT_ACK_COMULATE_USEC/TIME_TICK_STEP_USEC;
|
||||
|
||||
const int LATTICE_STATE_EMPTY=0;
|
||||
const int LATTICE_STATE_OCCUPIED=1;
|
||||
|
||||
|
||||
|
||||
|
||||
int count_last_frag_num_in_packet(const bizman_packet_t* packet)
|
||||
{
|
||||
int i=0,last_frag_num=0;
|
||||
bizman_slice_t* slice=(bizman_slice_t*)((char*)packet+LOAD_HEADER_LEN);
|
||||
for(i=0;i<packet->slice_num;i++)
|
||||
{
|
||||
if(slice->flags&SLICE_LAST_FRAG)
|
||||
{
|
||||
last_frag_num++;
|
||||
}
|
||||
slice=(bizman_slice_t* )((char*)slice+slice->slice_len);
|
||||
|
||||
}
|
||||
return last_frag_num;
|
||||
}
|
||||
recv_data_index_t* create_recv_data_index(bizman_packet_t* packet,int len,unsigned int src_ip,unsigned short src_port)
|
||||
{
|
||||
recv_data_index_t* index=NULL;
|
||||
index=(recv_data_index_t*)b_malloc(sizeof(recv_data_index_t));
|
||||
index->hook.quiddity=(void*)index;
|
||||
index->packet=packet;
|
||||
index->len=len;
|
||||
index->src_ip=src_ip;
|
||||
index->src_port=src_port;
|
||||
return index;
|
||||
}
|
||||
void free_recv_data_index(recv_data_index_t* target)
|
||||
{
|
||||
free(target->packet);
|
||||
free(target);
|
||||
}
|
||||
ack_task_t* create_ack_task(unsigned int dst_ip,unsigned short dst_port,uint32 stream_id,uint32 sequence){
|
||||
ack_task_t* ack_task=NULL;
|
||||
ack_task=(ack_task_t*)b_malloc(sizeof(ack_task_t));
|
||||
ack_task->hook.quiddity=(void*)ack_task;
|
||||
ack_task->dest_ip=dst_ip;
|
||||
ack_task->dest_port=dst_port;
|
||||
ack_task->sequence=sequence;
|
||||
ack_task->stream_id=stream_id;
|
||||
ack_task->flags|=FLAG_ACK_PKT;
|
||||
return ack_task;
|
||||
}
|
||||
void make_recv_key(unsigned char *key_buf,unsigned int src_ip,unsigned short src_port,uint32 stream_id)
|
||||
{
|
||||
memcpy(key_buf,&src_ip,sizeof(src_ip));
|
||||
memcpy(key_buf+sizeof(src_ip),&src_port,sizeof(src_port));
|
||||
memcpy(key_buf+sizeof(src_ip)+sizeof(src_port),&stream_id,sizeof(stream_id));
|
||||
}
|
||||
recv_stream_record_t* find_stream_record_in_hash(hash_tab_t *hash,unsigned int src_ip,unsigned short src_port,uint32 stream_id)
|
||||
{
|
||||
unsigned char key[sizeof(src_ip)+sizeof(src_port)+sizeof(stream_id)];
|
||||
make_recv_key(key,src_ip,src_port, stream_id);
|
||||
return (recv_stream_record_t*)_bizman_kernel_hash_sel(hash,key,sizeof(key));
|
||||
}
|
||||
int del_stream_record_in_hash(hash_tab_t *hash,unsigned int src_ip,unsigned short src_port,uint32 stream_id)
|
||||
{
|
||||
unsigned char key[sizeof(src_ip)+sizeof(src_port)+sizeof(stream_id)];
|
||||
make_recv_key(key,src_ip,src_port, stream_id);
|
||||
return _bizman_kernel_hash_del(hash,key,sizeof(key), NULL);
|
||||
}
|
||||
void add_record_to_hash(hash_tab_t *hash,unsigned int src_ip,unsigned short src_port,uint32 stream_id,recv_stream_record_t* value)
|
||||
{
|
||||
unsigned char key[sizeof(src_ip)+sizeof(src_port)+sizeof(stream_id)];
|
||||
make_recv_key(key,src_ip,src_port, stream_id);
|
||||
_bizman_kernel_hash_add(hash, key, sizeof(key), value);
|
||||
}
|
||||
int recv_stream_hash_expire(void *p)
|
||||
{
|
||||
recv_stream_record_t* record=(recv_stream_record_t*)p;
|
||||
int have_unread_data=FALSE;
|
||||
if(0==bizman_trylock(&(record->lock_ready_operate))){
|
||||
if(record->is_in_ready_queue==TRUE)
|
||||
{
|
||||
have_unread_data=TRUE;
|
||||
}
|
||||
bizman_unlock(&(record->lock_ready_operate));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(have_unread_data==TRUE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(get_time_tick()-record->last_edit_tick >TIMEOUT_RECV_STREAM_TICK||record->is_read_complete==TRUE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void free_recv_stream_value(void *p)
|
||||
{
|
||||
recv_stream_record_t* record=(recv_stream_record_t*)p;
|
||||
|
||||
unsigned int i=0;
|
||||
for(i=0;i<record->recv_window_size;i++)
|
||||
{
|
||||
if(LATTICE_STATE_OCCUPIED==record->ruler[i].state)
|
||||
{
|
||||
free(record->ruler[i].data_index->packet);
|
||||
free(record->ruler[i].data_index);
|
||||
}
|
||||
}
|
||||
free(record->ruler);
|
||||
//record already leave ack_timeout_queue and ready queue;
|
||||
//and core_recv_thread had stopped;
|
||||
list_index_t* p_list_index=NULL;
|
||||
recv_data_index_t* packet_index=NULL;
|
||||
|
||||
p_list_index=q_get_head(&(record->orderd_data_queue));
|
||||
while(NULL!=p_list_index)
|
||||
{
|
||||
packet_index=(recv_data_index_t*)(p_list_index->quiddity);
|
||||
free(packet_index->packet);
|
||||
free(packet_index);
|
||||
packet_index=NULL;
|
||||
p_list_index=q_get_head(&(record->orderd_data_queue));
|
||||
}
|
||||
|
||||
free(record);
|
||||
}
|
||||
void create_recv_stream_hash(hash_tab_t *hash)
|
||||
{
|
||||
_bizman_kernel_hash_create(hash, RELIABLE_STREAM_HASH_SIZE, NULL, NULL, recv_stream_hash_expire, free_recv_stream_value);
|
||||
}
|
||||
void destroy_recv_stream_hash(hash_tab_t *hash)
|
||||
{
|
||||
_bizman_kernel_hash_destroy(hash, NULL);
|
||||
}
|
||||
void expire_recv_stream_hash(hash_tab_t*hash)
|
||||
{
|
||||
_bizman_kernel_hash_expire(hash);
|
||||
}
|
||||
recv_stream_record_t* create_recv_record(unsigned int stream_id,unsigned int window_size)
|
||||
{
|
||||
recv_stream_record_t* record=NULL;
|
||||
record=(recv_stream_record_t*)b_malloc(sizeof(recv_stream_record_t));
|
||||
record->last_edit_tick=get_time_tick();
|
||||
record->record_create_tick=record->last_edit_tick;
|
||||
record->ready_hook.quiddity=(void*)record;
|
||||
record->ack_timeout_hook.quiddity=(void*)record;
|
||||
record->stream_id=stream_id;
|
||||
record->recv_window_size=window_size;
|
||||
record->ruler=(stream_recv_lattice_t*)b_malloc(sizeof(stream_recv_lattice_t)*window_size);
|
||||
bizman_init_lock(&(record->lock_ready_operate));
|
||||
return record;
|
||||
}
|
||||
|
||||
reliable_recv_space_t* create_reliable_recv_space(void)
|
||||
{
|
||||
reliable_recv_space_t* reliable_recv_space=NULL;
|
||||
reliable_recv_space=(reliable_recv_space_t*)b_malloc(sizeof(reliable_recv_space_t));
|
||||
create_recv_stream_hash(&(reliable_recv_space->stream_hash));
|
||||
bizman_init_lock(&(reliable_recv_space->mutexlock_ready_stream_index_queue));
|
||||
bizman_init_cond(&(reliable_recv_space->cond_have_data_to_read));
|
||||
reliable_recv_space->last_expire_time=get_time_tick();
|
||||
reliable_recv_space->accumulate_ack_num=DEFAULT_COMULATE_ACK_NUM;
|
||||
reliable_recv_space->accumulate_ack_timeout_tick=DEFAULT_ACK_COMULATE_TICK;
|
||||
reliable_recv_space->receive_window_size=DEFALUT_RECV_WINDOW_SIZE;
|
||||
return reliable_recv_space;
|
||||
}
|
||||
void isolate_recv_record(reliable_recv_space_t* reliable_recv_space,recv_stream_record_t* stream_record)
|
||||
{
|
||||
|
||||
bizman_lock(&(reliable_recv_space->mutexlock_ready_stream_index_queue));
|
||||
bizman_lock(&(stream_record->lock_ready_operate));
|
||||
|
||||
if(TRUE==stream_record->is_in_ready_queue)
|
||||
{
|
||||
q_leave_list(&(reliable_recv_space->ready_stream_index_queue), &(stream_record->ready_hook));
|
||||
stream_record->is_in_ready_queue=FALSE;
|
||||
}
|
||||
if(TRUE==stream_record->is_in_ack_timeout_queue)
|
||||
{
|
||||
q_leave_list(&(reliable_recv_space->ack_timeout_queue),&(stream_record->ack_timeout_hook));
|
||||
stream_record->is_in_ack_timeout_queue=FALSE;
|
||||
}
|
||||
bizman_unlock(&(stream_record->lock_ready_operate));
|
||||
bizman_unlock(&(reliable_recv_space->mutexlock_ready_stream_index_queue));
|
||||
|
||||
}
|
||||
void destroy_reliable_recv_space(reliable_recv_space_t* reliable_recv_space)
|
||||
{
|
||||
list_index_t* p_index_ready=NULL;
|
||||
list_index_t* pl_timeout_ack_record=NULL,*pl_to_ack=NULL;
|
||||
ack_task_t* ack_task=NULL;
|
||||
recv_stream_record_t* record=NULL;
|
||||
//leave ready queue
|
||||
p_index_ready=q_get_head(&(reliable_recv_space->ready_stream_index_queue));
|
||||
while(p_index_ready!=NULL)
|
||||
{
|
||||
record=(recv_stream_record_t*)(p_index_ready->quiddity);
|
||||
bizman_lock(&(record->lock_ready_operate));
|
||||
record->is_in_ready_queue=FALSE;
|
||||
bizman_unlock(&(record->lock_ready_operate));
|
||||
p_index_ready=q_get_head(&(reliable_recv_space->ready_stream_index_queue));
|
||||
}
|
||||
// free timeout ack
|
||||
pl_timeout_ack_record=q_get_head(&(reliable_recv_space->ack_timeout_queue));
|
||||
while(pl_timeout_ack_record!=NULL)
|
||||
{
|
||||
record=(recv_stream_record_t*)(pl_timeout_ack_record->quiddity);
|
||||
record->is_in_ack_timeout_queue=FALSE;
|
||||
free(record->timeout_ack);
|
||||
record->timeout_ack=NULL;
|
||||
pl_timeout_ack_record=q_get_head(&(reliable_recv_space->ack_timeout_queue));
|
||||
}
|
||||
//free ack_task
|
||||
pl_to_ack=q_get_head(&(reliable_recv_space->to_ack_queue));
|
||||
while(pl_to_ack!=NULL)
|
||||
{
|
||||
ack_task=(ack_task_t*)(pl_to_ack->quiddity);
|
||||
free(ack_task);
|
||||
pl_to_ack=q_get_head(&(reliable_recv_space->to_ack_queue));
|
||||
}
|
||||
destroy_recv_stream_hash(&(reliable_recv_space->stream_hash));
|
||||
free(reliable_recv_space);
|
||||
|
||||
}
|
||||
int add_raw_packet(reliable_recv_space_t* reliable_recv_handle,unsigned int src_ip,unsigned short src_port,bizman_packet_t* packet_data,int packet_len)
|
||||
{
|
||||
|
||||
recv_stream_record_t* stream_record=NULL;
|
||||
recv_data_index_t* packet_index=NULL;
|
||||
int record_index=packet_data->sequence%reliable_recv_handle->receive_window_size;
|
||||
ack_task_t *ack_task=NULL;
|
||||
unsigned int i=0;
|
||||
int last_frag_num;
|
||||
int flag_stream_complete=FALSE;
|
||||
#ifdef BIZMAN_DEBUG_DETAILS
|
||||
printf("Recv DAT:stream=%d seq=%d\n",packet_data->id,packet_data->sequence);
|
||||
#endif
|
||||
//locate stream record in hash
|
||||
|
||||
if(packet_data->flags&FLAG_EST_STREAM&&packet_data->sequence==START_SEQ_NUM)
|
||||
{
|
||||
stream_record=find_stream_record_in_hash(&(reliable_recv_handle->stream_hash),src_ip,src_port,packet_data->id);
|
||||
if(stream_record!=NULL)
|
||||
{
|
||||
if(get_time_tick()-stream_record->record_create_tick>FORCE_EST_INTERVAL/TIME_TICK_STEP_USEC)
|
||||
{
|
||||
isolate_recv_record(reliable_recv_handle,stream_record);
|
||||
if(0!=del_stream_record_in_hash(&(reliable_recv_handle->stream_hash),src_ip,src_port,packet_data->id))
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG_DETAILS
|
||||
printf("Del:stream=%d seq=%d failed\n",packet_data->id,packet_data->sequence);
|
||||
#endif
|
||||
}
|
||||
stream_record=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
stream_record=find_stream_record_in_hash(&(reliable_recv_handle->stream_hash),src_ip,src_port,packet_data->id);
|
||||
if(stream_record==NULL)
|
||||
{
|
||||
stream_record=create_recv_record(packet_data->id,reliable_recv_handle->receive_window_size);
|
||||
add_record_to_hash(&(reliable_recv_handle->stream_hash), src_ip,src_port,packet_data->id, stream_record);
|
||||
}
|
||||
if(packet_data->flags&FLAG_NEED_ACK)
|
||||
{
|
||||
if(packet_data->sequence==0&&stream_record->max_ordered_seq==0)//0 is not a valid sequence at begining
|
||||
{
|
||||
|
||||
free(packet_data);//error
|
||||
return -1;
|
||||
}
|
||||
if((packet_data->sequence > stream_record->max_ordered_seq||packet_data->sequence==0) && //when uint32 seq overflow,its turn to 0
|
||||
packet_data->sequence <= stream_record->latest_ack_seq+reliable_recv_handle->receive_window_size&&
|
||||
stream_record->ruler[record_index].state==LATTICE_STATE_EMPTY)
|
||||
{
|
||||
|
||||
packet_index=create_recv_data_index(packet_data, packet_len, src_ip, src_port);
|
||||
stream_record->ruler[record_index].state=LATTICE_STATE_OCCUPIED;
|
||||
stream_record->ruler[record_index].sequence=packet_data->sequence;
|
||||
stream_record->ruler[record_index].data_index=packet_index;
|
||||
|
||||
record_index=(stream_record->max_ordered_seq+1)%reliable_recv_handle->receive_window_size;
|
||||
for(i=0;i<reliable_recv_handle->receive_window_size;i++)
|
||||
{
|
||||
if(stream_record->ruler[record_index].state==LATTICE_STATE_OCCUPIED)
|
||||
{
|
||||
if(stream_record->ruler[record_index].data_index->packet->flags&FLAG_LAST_PKT)
|
||||
{
|
||||
flag_stream_complete=TRUE;
|
||||
}
|
||||
last_frag_num=count_last_frag_num_in_packet(stream_record->ruler[record_index].data_index->packet);
|
||||
bizman_lock(&(stream_record->lock_ready_operate));
|
||||
stream_record->chunk_num+=last_frag_num;
|
||||
q_join_tail(&(stream_record->orderd_data_queue),&(stream_record->ruler[record_index].data_index->hook));
|
||||
stream_record->ruler[record_index].data_index=NULL;
|
||||
stream_record->ruler[record_index].state=LATTICE_STATE_EMPTY;
|
||||
stream_record->ordered_unack_num++;
|
||||
stream_record->max_ordered_seq++;
|
||||
stream_record->is_recv_complete=flag_stream_complete;
|
||||
//no chunk_mode or chunk_mode and have last frag
|
||||
if(FALSE==stream_record->is_in_ready_queue
|
||||
&&(reliable_recv_handle->chunk_mode!=TRUE||last_frag_num>0))
|
||||
{
|
||||
|
||||
stream_record->is_in_ready_queue=TRUE;
|
||||
bizman_unlock(&(stream_record->lock_ready_operate));
|
||||
|
||||
bizman_lock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
q_join_tail(&(reliable_recv_handle->ready_stream_index_queue), &(stream_record->ready_hook));
|
||||
|
||||
if(reliable_recv_handle->choke_mode==TRUE)
|
||||
{
|
||||
bizman_cond_signal(&(reliable_recv_handle->cond_have_data_to_read));
|
||||
}
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
bizman_unlock(&(stream_record->lock_ready_operate));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
break;///uncontinous window
|
||||
}
|
||||
record_index=(record_index+1)%reliable_recv_handle->receive_window_size;
|
||||
}
|
||||
// if((packet_data->flags&FLAG_LAST_PKT&&stream_record->ordered_unack_num>0)||
|
||||
if(stream_record->ordered_unack_num>=reliable_recv_handle->accumulate_ack_num)//ack immediately
|
||||
{
|
||||
ack_task=create_ack_task(src_ip, src_port, stream_record->stream_id, stream_record->max_ordered_seq);
|
||||
ack_task->father_stream=stream_record;
|
||||
q_join_tail(&(reliable_recv_handle->to_ack_queue), &(ack_task->hook));
|
||||
stream_record->ordered_unack_num=0;
|
||||
stream_record->latest_ack_seq=stream_record->max_ordered_seq;
|
||||
if(stream_record->is_in_ack_timeout_queue)
|
||||
{
|
||||
q_leave_list(&(reliable_recv_handle->ack_timeout_queue),&(stream_record->ack_timeout_hook));
|
||||
free(stream_record->timeout_ack);
|
||||
stream_record->timeout_ack=NULL;
|
||||
stream_record->is_in_ack_timeout_queue=FALSE;
|
||||
}
|
||||
}
|
||||
else if(stream_record->ordered_unack_num>0)//ack later
|
||||
{
|
||||
if(stream_record->is_in_ack_timeout_queue==FALSE)//no ack in time wait
|
||||
{
|
||||
stream_record->timeout_ack=create_ack_task(src_ip, src_port, stream_record->stream_id, stream_record->max_ordered_seq);
|
||||
stream_record->timeout_ack->father_stream=stream_record;
|
||||
q_join_tail(&(reliable_recv_handle->ack_timeout_queue),&(stream_record->ack_timeout_hook));
|
||||
stream_record->is_in_ack_timeout_queue=TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_record->timeout_ack->sequence=stream_record->max_ordered_seq;
|
||||
}
|
||||
}
|
||||
else//nothing to ack
|
||||
{
|
||||
;
|
||||
}
|
||||
stream_record->last_edit_tick=get_time_tick();
|
||||
}
|
||||
else//resend ack
|
||||
{
|
||||
ack_task=create_ack_task(src_ip, src_port,stream_record->stream_id, stream_record->max_ordered_seq);
|
||||
ack_task->father_stream=stream_record;
|
||||
stream_record->latest_ack_seq=stream_record->max_ordered_seq;
|
||||
q_join_tail(&(reliable_recv_handle->to_ack_queue),&(ack_task->hook));
|
||||
free(packet_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_index=create_recv_data_index(packet_data, packet_len, src_ip, src_port);
|
||||
last_frag_num=count_last_frag_num_in_packet(packet_data);
|
||||
bizman_lock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
bizman_lock(&(stream_record->lock_ready_operate));
|
||||
stream_record->chunk_num+=last_frag_num;
|
||||
q_join_tail(&(stream_record->orderd_data_queue),&(packet_index->hook));
|
||||
if(FALSE==stream_record->is_in_ready_queue)
|
||||
{
|
||||
if(reliable_recv_handle->chunk_mode!=TRUE||last_frag_num>0)
|
||||
{
|
||||
|
||||
q_join_tail(&(reliable_recv_handle->ready_stream_index_queue), &(stream_record->ready_hook));
|
||||
stream_record->is_in_ready_queue=TRUE;
|
||||
if(reliable_recv_handle->choke_mode==TRUE)
|
||||
{
|
||||
bizman_cond_signal(&(reliable_recv_handle->cond_have_data_to_read));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
stream_record->is_recv_complete=flag_stream_complete;
|
||||
bizman_unlock(&(stream_record->lock_ready_operate));
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
}
|
||||
if(get_time_tick()-reliable_recv_handle->last_expire_time>TIMEOUT_RECV_STREAM_TICK)
|
||||
{
|
||||
expire_recv_stream_hash(&(reliable_recv_handle->stream_hash));
|
||||
reliable_recv_handle->last_expire_time=get_time_tick();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ack_task_t* get_timewait_ack(reliable_recv_space_t* reliable_recv_handle)
|
||||
{
|
||||
list_index_t *p_list=NULL;
|
||||
recv_stream_record_t* father_stream=NULL;
|
||||
ack_task_t* target=NULL;
|
||||
p_list=q_read_head(&(reliable_recv_handle->ack_timeout_queue));
|
||||
if(p_list!=NULL)
|
||||
{
|
||||
father_stream=(recv_stream_record_t*)(p_list->quiddity);
|
||||
if(get_time_tick()-father_stream->last_edit_tick > reliable_recv_handle->accumulate_ack_timeout_tick)
|
||||
{
|
||||
q_get_head(&(reliable_recv_handle->ack_timeout_queue));
|
||||
|
||||
father_stream->is_in_ack_timeout_queue=FALSE;
|
||||
father_stream->latest_ack_seq=father_stream->max_ordered_seq;
|
||||
target=father_stream->timeout_ack;
|
||||
father_stream->timeout_ack=NULL;
|
||||
}
|
||||
|
||||
}
|
||||
return target;
|
||||
}
|
||||
ack_task_t* get_definate_ack(reliable_recv_space_t* reliable_recv_handle)
|
||||
{
|
||||
list_index_t *p_list=NULL;
|
||||
ack_task_t* target=NULL;
|
||||
recv_stream_record_t* father_stream=NULL;
|
||||
p_list=q_get_head(&(reliable_recv_handle->to_ack_queue));
|
||||
if(p_list!=NULL)
|
||||
{
|
||||
target=(ack_task_t*)p_list->quiddity;
|
||||
father_stream=(recv_stream_record_t*)target->father_stream;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
int get_ack_task(reliable_recv_space_t* reliable_recv_handle,ack_task_t* send_ack_task)
|
||||
{
|
||||
ack_task_t* target=NULL;
|
||||
static uint32 s62_ack_seq=0;
|
||||
target=get_timewait_ack(reliable_recv_handle);
|
||||
if(target==NULL)
|
||||
target=get_definate_ack(reliable_recv_handle);
|
||||
if(target==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(target->stream_id==62)
|
||||
{
|
||||
s62_ack_seq=target->sequence;
|
||||
}
|
||||
send_ack_task->dest_ip=target->dest_ip;
|
||||
send_ack_task->dest_port=target->dest_port;
|
||||
memcpy((char*)(send_ack_task),(char*)target,sizeof(ack_task_t));
|
||||
free(target);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
int read_slice_from_packet(bizman_packet_t*packet,char* buf,int buf_len,int *offset,int *is_chunk_end)
|
||||
{
|
||||
int i=0;
|
||||
bizman_slice_t* start_slice=NULL;
|
||||
int read_len=0,slice_left_len=0;
|
||||
|
||||
if(*offset>=packet->len)
|
||||
return 0;
|
||||
if(0==*offset)
|
||||
{
|
||||
*offset=LOAD_HEADER_LEN+SLICE_HEADER_LEN;
|
||||
}
|
||||
if(0<*offset<LOAD_HEADER_LEN+SLICE_HEADER_LEN)
|
||||
{
|
||||
//fatal error;
|
||||
}
|
||||
start_slice=(bizman_slice_t*)((char*)packet+LOAD_HEADER_LEN);
|
||||
for(i=0;i<packet->slice_num;i++)
|
||||
{
|
||||
if(((char*)start_slice+start_slice->slice_len)-(char*)packet > *offset)
|
||||
break;
|
||||
else
|
||||
start_slice=(bizman_slice_t*)((char*)start_slice+start_slice->slice_len);
|
||||
}
|
||||
slice_left_len=(char*)start_slice-(char*)packet+start_slice->slice_len-*offset;
|
||||
read_len=MIN(buf_len,slice_left_len);
|
||||
memcpy(buf,(char*)packet+*offset,read_len);
|
||||
if(slice_left_len>buf_len){
|
||||
*offset+=buf_len;
|
||||
read_len=buf_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*offset+=slice_left_len+SLICE_HEADER_LEN;
|
||||
read_len=slice_left_len;
|
||||
}
|
||||
if(start_slice->flags&SLICE_LAST_FRAG&&read_len==slice_left_len)
|
||||
*is_chunk_end=TRUE;
|
||||
else
|
||||
*is_chunk_end=FALSE;
|
||||
return read_len;
|
||||
}
|
||||
/*
|
||||
is_complete=0 insufficent buffer,copy buf_len content;
|
||||
is_complete=1 stream and chunk complete;
|
||||
is_complete=2 chunk complete;
|
||||
*/
|
||||
//lock space->lock stream
|
||||
int copy_recv_data(reliable_recv_space_t* reliable_recv_handle,char* buf,int buf_len,unsigned int *src_ip,unsigned short *src_port,unsigned int *stream_id,unsigned int* is_complete)
|
||||
{
|
||||
list_index_t *stream_list=NULL,*packet_index_list=NULL;
|
||||
recv_stream_record_t* ready_stream=NULL;
|
||||
recv_data_index_t* ready_data_index=NULL;
|
||||
bizman_packet_t* packet=NULL;
|
||||
int already_read_len=0,this_read_len=0;
|
||||
int is_chunk_end=FALSE,is_no_data_left=FALSE;
|
||||
*is_complete=BIZMAN_READ_CRAM;
|
||||
struct timespec recv_timeout;
|
||||
|
||||
bizman_lock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
while(stream_list==NULL){
|
||||
|
||||
stream_list=q_read_head(&(reliable_recv_handle->ready_stream_index_queue));
|
||||
if(NULL==stream_list)
|
||||
{
|
||||
if(reliable_recv_handle->choke_mode==TRUE)
|
||||
{
|
||||
if(reliable_recv_handle->choke_timeout_mili_seconds==0)
|
||||
{
|
||||
bizman_cond_wait(&(reliable_recv_handle->cond_have_data_to_read),&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
}
|
||||
else
|
||||
{
|
||||
recv_timeout.tv_sec=time(NULL)+reliable_recv_handle->choke_timeout_mili_seconds/1000;
|
||||
recv_timeout.tv_nsec=(reliable_recv_handle->choke_timeout_mili_seconds %1000)*1000000;
|
||||
if(0!=bizman_cond_timedwait(&(reliable_recv_handle->cond_have_data_to_read),&(reliable_recv_handle->mutexlock_ready_stream_index_queue),&recv_timeout))
|
||||
{
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ready_stream=(recv_stream_record_t*)(stream_list->quiddity);
|
||||
bizman_lock(&(ready_stream->lock_ready_operate));
|
||||
// bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
|
||||
packet_index_list=q_read_head(&(ready_stream->orderd_data_queue));
|
||||
if(NULL==packet_index_list)
|
||||
{
|
||||
bizman_unlock(&(ready_stream->lock_ready_operate));
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
return 0;
|
||||
}
|
||||
ready_data_index=(recv_data_index_t*)(packet_index_list->quiddity);
|
||||
packet=ready_data_index->packet;
|
||||
*src_ip=ready_data_index->src_ip;
|
||||
*src_port=ready_data_index->src_port;
|
||||
*stream_id=ready_stream->stream_id;
|
||||
|
||||
while(FALSE==is_chunk_end && FALSE==is_no_data_left && already_read_len<buf_len)
|
||||
{
|
||||
this_read_len=read_slice_from_packet(packet, buf+already_read_len, buf_len-already_read_len,&(ready_stream->read_offset), &is_chunk_end);
|
||||
|
||||
if(this_read_len==0)
|
||||
{
|
||||
|
||||
ready_stream->read_offset=0;
|
||||
packet_index_list=q_get_head(&(ready_stream->orderd_data_queue));
|
||||
free_recv_data_index((recv_data_index_t*)(packet_index_list->quiddity));
|
||||
packet_index_list=q_read_head(&(ready_stream->orderd_data_queue));
|
||||
if(NULL==packet_index_list)//no data left in stream
|
||||
{
|
||||
// bizman_lock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
stream_list=q_get_head(&(reliable_recv_handle->ready_stream_index_queue));//remove from ready stream queue
|
||||
// bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
ready_stream->is_in_ready_queue=FALSE;
|
||||
if(TRUE==ready_stream->is_recv_complete)//stream is finished
|
||||
{
|
||||
*is_complete|=BIZMAN_READ_STREAM;
|
||||
ready_stream->is_read_complete=TRUE;
|
||||
}
|
||||
is_no_data_left=TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ready_data_index=(recv_data_index_t*)(packet_index_list->quiddity);
|
||||
packet=ready_data_index->packet;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
already_read_len+=this_read_len;
|
||||
|
||||
}
|
||||
}
|
||||
if(is_chunk_end==TRUE)
|
||||
{
|
||||
*is_complete|=BIZMAN_READ_CHUNK;
|
||||
ready_stream->chunk_num--;
|
||||
if(reliable_recv_handle->chunk_mode==TRUE&&ready_stream->chunk_num==0)
|
||||
{
|
||||
// bizman_lock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
stream_list=q_get_head(&(reliable_recv_handle->ready_stream_index_queue));//remove from ready stream queue
|
||||
// bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
ready_stream->is_in_ready_queue=FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("uncomplete chunk\n");
|
||||
}
|
||||
bizman_unlock(&(reliable_recv_handle->mutexlock_ready_stream_index_queue));
|
||||
bizman_unlock(&(ready_stream->lock_ready_operate));
|
||||
return already_read_len;
|
||||
}
|
||||
|
||||
84
src/support/Businessman/reliable_recv.h
Normal file
84
src/support/Businessman/reliable_recv.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef _BIZMAN_RELIABLE_RECV_H_INCLUDE_
|
||||
#define _BIZMAN_RELIABLE_RECV_H_INCLUDE_
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "businessman_lock.h"
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_packet.h"
|
||||
#include "businessman_base.h"
|
||||
typedef struct _businessman_recv_data_index_t{
|
||||
int len;
|
||||
bizman_packet_t *packet;
|
||||
list_index_t hook;
|
||||
uint32 src_ip;
|
||||
uint16 src_port;
|
||||
}recv_data_index_t;
|
||||
typedef struct _businessman_relaible_recv_lattice_t{
|
||||
int state;
|
||||
uint32 sequence;
|
||||
recv_data_index_t *data_index;
|
||||
}stream_recv_lattice_t;
|
||||
typedef struct _businessman_recv_ack_task_t{
|
||||
unsigned int dest_ip;
|
||||
unsigned short dest_port;
|
||||
uint32 stream_id;
|
||||
uint32 sequence;
|
||||
uint8 flags;
|
||||
void* father_stream;
|
||||
list_index_t hook;
|
||||
|
||||
}ack_task_t;
|
||||
typedef struct _businessman_reliable_recv_record_t{
|
||||
unsigned int stream_id;
|
||||
time_tick_t record_create_tick;
|
||||
time_tick_t last_edit_tick;
|
||||
uint32 max_ordered_seq;
|
||||
uint32 latest_ack_seq;
|
||||
unsigned int ordered_unack_num;
|
||||
stream_recv_lattice_t *ruler;
|
||||
queue_head_t orderd_data_queue;
|
||||
|
||||
bizman_lock_t lock_ready_operate; //protect in queue and out queue operation
|
||||
int is_in_ready_queue;
|
||||
list_index_t ready_hook;//hook to ready stream index queue
|
||||
|
||||
int is_in_ack_timeout_queue;
|
||||
list_index_t ack_timeout_hook;
|
||||
ack_task_t *timeout_ack; //use stream's hook to index timeout_ack
|
||||
|
||||
int read_offset;//only access by user app thread
|
||||
int chunk_num;//un handled chunk_num;
|
||||
int is_recv_complete;//received every packet of the stream
|
||||
int is_read_complete;//read every packet of the stream,its empty already.
|
||||
unsigned int recv_window_size;
|
||||
}recv_stream_record_t;
|
||||
|
||||
typedef struct _businessman_reliable_recv_space_t
|
||||
{
|
||||
hash_tab_t stream_hash;
|
||||
queue_head_t to_ack_queue;
|
||||
queue_head_t ack_timeout_queue;
|
||||
queue_head_t ready_stream_index_queue; //only user app thread can get head from this queue
|
||||
unsigned int chunk_mode;
|
||||
unsigned int choke_mode;
|
||||
unsigned int choke_timeout_mili_seconds;
|
||||
bizman_lock_t mutexlock_ready_stream_index_queue;
|
||||
bizman_cond_t cond_have_data_to_read;
|
||||
time_tick_t last_expire_time;
|
||||
//parameter
|
||||
unsigned int receive_window_size;
|
||||
unsigned int accumulate_ack_num;
|
||||
time_tick_t accumulate_ack_timeout_tick;
|
||||
//time_tick_t ack_smooth_timeout_tick;
|
||||
}reliable_recv_space_t;
|
||||
reliable_recv_space_t* create_reliable_recv_space(void);
|
||||
void destroy_reliable_recv_space(reliable_recv_space_t* reliable_recv_space);
|
||||
int add_raw_packet(reliable_recv_space_t* reliable_recv_handle,unsigned int src_ip,unsigned short src_port,bizman_packet_t* packet_data,int packet_len);
|
||||
|
||||
int copy_recv_data(reliable_recv_space_t* reliable_recv_handle,char* buf,int buf_len,unsigned int *src_ip,unsigned short *src_port,unsigned int *stream_id,unsigned int* is_complete);
|
||||
/*return ack packet length(>0) when success
|
||||
return -1 when failed
|
||||
return 0 when no ack task left*/
|
||||
int get_ack_task(reliable_recv_space_t* reliable_recv_handle,ack_task_t* send_ack_task);
|
||||
#endif //_BIZMAN_RELIABLE_RECV_H_INCLUDE_
|
||||
|
||||
524
src/support/Businessman/reliable_send.cpp
Normal file
524
src/support/Businessman/reliable_send.cpp
Normal file
@@ -0,0 +1,524 @@
|
||||
#include <stdlib.h>
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_error.h"
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_time.h"
|
||||
#include "reliable_send.h"
|
||||
|
||||
|
||||
const time_tick_t TIMEOUT_SEND_STREAM_TICK=TIMEOUT_SEND_STREAM_USEC/TIME_TICK_STEP_USEC;
|
||||
|
||||
|
||||
const unsigned int RELIABLE_SEND_HASH_SIZE=1024*1024;
|
||||
|
||||
send_data_index_t* create_send_data_index(send_data_refer_t* refer)
|
||||
{
|
||||
send_data_index_t* block=NULL;
|
||||
block=(send_data_index_t*)b_malloc(sizeof(send_data_index_t));
|
||||
block->hook.quiddity=(void*)block;
|
||||
block->refer_index=refer;
|
||||
return block;
|
||||
}
|
||||
void free_index_and_data(send_data_index_t* p_data_index){
|
||||
free_refer_and_data(p_data_index->refer_index);
|
||||
free(p_data_index);
|
||||
}
|
||||
send_stream_t* create_send_stream(sub_send_task_t* smoothed_task,unsigned int window_size)
|
||||
{
|
||||
send_stream_t* stream=NULL;
|
||||
unsigned int i=0;
|
||||
stream=(send_stream_t*)b_malloc(sizeof(send_stream_t));
|
||||
stream->stream_id=smoothed_task->stream_id;
|
||||
stream->dest_ip=smoothed_task->dest_ip;
|
||||
stream->dest_port=smoothed_task->dest_port;
|
||||
stream->is_relaible=smoothed_task->is_reliable;
|
||||
stream->last_edit_tick=get_time_tick();
|
||||
stream->bigger_sequence=START_SEQ_NUM;//sequence form 1,no zero
|
||||
stream->task=(stream_send_pane_t*)b_malloc(sizeof(stream_send_pane_t)*window_size);
|
||||
for(i=0;i<window_size;i++)
|
||||
{
|
||||
stream->task[i].order=i;
|
||||
stream->task[i].hook.quiddity=(void*)(&(stream->task[i]));
|
||||
stream->task[i].is_relaible=stream->is_relaible;
|
||||
stream->task[i].father_stream=(void*)stream;
|
||||
}
|
||||
stream->send_window_size=window_size;
|
||||
return stream;
|
||||
}
|
||||
int add_send_hash(hash_tab_t* send_hash,unsigned int stream_id,send_stream_t* stream)
|
||||
{
|
||||
return _bizman_kernel_hash_add(send_hash, (uchar*)(&stream_id), sizeof(stream_id), (void*)stream);
|
||||
}
|
||||
int send_stream_hash_expire(void* p)
|
||||
{
|
||||
send_stream_t*p_stream=(send_stream_t *)p;
|
||||
if(get_time_tick()-p_stream->last_edit_tick >TIMEOUT_SEND_STREAM_TICK&&p_stream->in_use_task_num==0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
send_stream_t* find_send_hash(hash_tab_t*stream_table,unsigned int stream_id)
|
||||
{
|
||||
return (send_stream_t*)_bizman_kernel_hash_sel(stream_table, (uchar*)(&stream_id),sizeof(stream_id));
|
||||
}
|
||||
void free_send_stream(void* p)
|
||||
{
|
||||
send_stream_t* stream=(send_stream_t*)p;
|
||||
list_index_t*p_list=NULL;
|
||||
send_data_index_t*p_data;
|
||||
//stream pane must leave timeout queue and task queue first before destroy the stream
|
||||
free(stream->task);
|
||||
while(NULL!=(p_list=q_get_head(&(stream->data_queue))))
|
||||
{
|
||||
p_data=(send_data_index_t*)(p_list->quiddity);
|
||||
free_index_and_data(p_data);
|
||||
}
|
||||
free(stream);
|
||||
}
|
||||
|
||||
int creat_reliable_send_hash(hash_tab_t* reliable_send_hash)
|
||||
{
|
||||
return _bizman_kernel_hash_create(reliable_send_hash, RELIABLE_SEND_HASH_SIZE, NULL, NULL, send_stream_hash_expire, free_send_stream);
|
||||
}
|
||||
int expire_send_hash(hash_tab_t* reliable_send_hash)
|
||||
{
|
||||
return _bizman_kernel_hash_expire(reliable_send_hash);
|
||||
}
|
||||
|
||||
void add_data_to_stream(send_stream_t* target_stream,send_data_index_t* data_index)
|
||||
{
|
||||
if(target_stream->bigger_sequence==START_SEQ_NUM)
|
||||
{
|
||||
data_index->refer_index->packet->flags|=FLAG_EST_STREAM;
|
||||
}
|
||||
data_index->refer_index->packet->sequence=target_stream->bigger_sequence;
|
||||
target_stream->bigger_sequence++;
|
||||
q_join_tail(&(target_stream->data_queue), &(data_index->hook));
|
||||
}
|
||||
//when new smoothed data block add, do update to assign new block to idle task
|
||||
void update_stream_task(reliable_send_space_t* send_space,send_stream_t* target_stream)
|
||||
{
|
||||
unsigned int i=0;
|
||||
list_index_t* p_list=NULL;
|
||||
if(target_stream->in_use_task_num==send_space->send_widow_size)
|
||||
return;
|
||||
for(i=0;i<send_space->send_widow_size;i++){
|
||||
if(target_stream->task[i].state==PANE_STATE_SPARE)
|
||||
{
|
||||
p_list=q_get_head(&(target_stream->data_queue));
|
||||
if(p_list!=NULL)
|
||||
{
|
||||
target_stream->task[i].dest_ip=target_stream->dest_ip;
|
||||
target_stream->task[i].dest_port=target_stream->dest_port;
|
||||
target_stream->task[i].index_data=(send_data_index_t*)p_list->quiddity;
|
||||
target_stream->task[i].state=PANE_STATE_WAIT_SEND;
|
||||
|
||||
q_join_tail(&(send_space->to_send_queue),&(target_stream->task[i].hook));
|
||||
|
||||
target_stream->in_use_task_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void reuse_stream_pane(reliable_send_space_t* send_space,stream_send_pane_t *idle_pane){
|
||||
send_stream_t* father_stream=NULL;
|
||||
list_index_t* pl_next=NULL;
|
||||
father_stream=(send_stream_t*)idle_pane->father_stream;
|
||||
free_index_and_data(idle_pane->index_data);
|
||||
send_space->stat_cached_packet_num--;
|
||||
pl_next=q_get_head(&(father_stream->data_queue));
|
||||
if(pl_next==NULL)
|
||||
{
|
||||
idle_pane->state=PANE_STATE_SPARE;
|
||||
idle_pane->index_data=NULL;
|
||||
idle_pane->send_times=0;
|
||||
father_stream->in_use_task_num--;
|
||||
}
|
||||
else
|
||||
{
|
||||
idle_pane->state=PANE_STATE_WAIT_SEND;
|
||||
idle_pane->index_data=(send_data_index_t*)(pl_next->quiddity);
|
||||
idle_pane->send_times=0;
|
||||
q_join_tail(&(send_space->to_send_queue), &(idle_pane->hook));
|
||||
}
|
||||
}
|
||||
void timeout_stream_pane(reliable_send_space_t* send_space,stream_send_pane_t *sended_pane)
|
||||
{
|
||||
send_stream_t* father_stream=NULL;
|
||||
father_stream=(send_stream_t*)sended_pane->father_stream;
|
||||
sended_pane->last_send_time=get_time_tick();
|
||||
sended_pane->state=PANE_STATE_TIME_OUT;
|
||||
sended_pane->send_times++;
|
||||
q_join_tail(&(send_space->timeout_queue[sended_pane->send_times-1]), &(sended_pane->hook));
|
||||
|
||||
|
||||
}
|
||||
void clear_send_stream(reliable_send_space_t* send_space,send_stream_t* target_stream)
|
||||
{
|
||||
list_index_t* pl_data=NULL;
|
||||
send_data_index_t* p_data_index=NULL;
|
||||
unsigned int i=0;
|
||||
pl_data=q_get_head(&(target_stream->data_queue));
|
||||
while(pl_data!=NULL)
|
||||
{
|
||||
p_data_index=(send_data_index_t*)(pl_data->quiddity);
|
||||
free_index_and_data(p_data_index);
|
||||
pl_data=q_get_head(&(target_stream->data_queue));
|
||||
send_space->stat_cached_packet_num--;
|
||||
send_space->stat_frozen_pkts_num++;
|
||||
}
|
||||
for(i=0;i<send_space->send_widow_size;i++){
|
||||
switch (target_stream->task[i].state)
|
||||
{
|
||||
case PANE_STATE_SPARE:
|
||||
break;
|
||||
case PANE_STATE_WAIT_SEND:
|
||||
q_leave_list(&(send_space->to_send_queue),&(target_stream->task[i].hook));
|
||||
free_index_and_data(target_stream->task[i].index_data);
|
||||
target_stream->task[i].index_data=NULL;
|
||||
target_stream->in_use_task_num--;
|
||||
send_space->stat_cached_packet_num--;
|
||||
send_space->stat_frozen_pkts_num++;
|
||||
break;
|
||||
case PANE_STATE_TIME_OUT:
|
||||
q_leave_list(&(send_space->timeout_queue[target_stream->task[i].send_times-1]), &(target_stream->task[i].hook));
|
||||
free_index_and_data(target_stream->task[i].index_data);
|
||||
target_stream->task[i].index_data=NULL;
|
||||
target_stream->in_use_task_num--;
|
||||
send_space->stat_frozen_pkts_num++;
|
||||
send_space->stat_cached_packet_num--;
|
||||
break;
|
||||
default:
|
||||
#ifdef BIZMAN_DEBUG
|
||||
fprintf(stderr,"error state at %s:%d\n",__FILE__,__LINE__);
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
target_stream->task[i].state=PANE_STATE_SPARE;
|
||||
target_stream->task[i].send_times=0;
|
||||
target_stream->task[i].last_send_time=0;
|
||||
}
|
||||
target_stream->last_edit_tick=get_time_tick();
|
||||
target_stream->is_unreachable=TRUE;
|
||||
target_stream->forzen_time_stamp=target_stream->last_edit_tick;
|
||||
target_stream->bigger_sequence=START_SEQ_NUM;
|
||||
target_stream->in_use_task_num=0;
|
||||
}
|
||||
|
||||
stream_send_pane_t *get_pane_from_to_send(reliable_send_space_t* reliable_send_space)
|
||||
{
|
||||
list_index_t *p_list=NULL;
|
||||
stream_send_pane_t* pane=NULL;
|
||||
p_list=q_get_head(&(reliable_send_space->to_send_queue));
|
||||
if(NULL==p_list)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pane=(stream_send_pane_t*)(p_list->quiddity);
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
reliable_send_space_t* create_reliable_send_space()
|
||||
{
|
||||
reliable_send_space_t* core_reliable_send_space=NULL;
|
||||
core_reliable_send_space=(reliable_send_space_t*)b_malloc(sizeof(reliable_send_space_t));
|
||||
if(NULL==core_reliable_send_space)
|
||||
{
|
||||
set_error(ERROR_TYPE_OUTOFMEM);
|
||||
return NULL;
|
||||
}
|
||||
creat_reliable_send_hash(&(core_reliable_send_space->stream_hash));
|
||||
|
||||
core_reliable_send_space->cached_pkts_num_limit=0;
|
||||
core_reliable_send_space->resend_base_tick=DEFAULT_TIMEOUT_RELIABLE_SEND_BASE_TICK;
|
||||
core_reliable_send_space->send_widow_size=DEFALUT_SEND_WINDOW_SIZE;
|
||||
core_reliable_send_space->frozen_stream_interval=DEFAULT_STREAM_FROZEN_TICK_INTERVAL;
|
||||
core_reliable_send_space->resend_times=MAX_RESEND_TIMES;
|
||||
return core_reliable_send_space;
|
||||
}
|
||||
void destroy_reliable_send_space(reliable_send_space_t* reliable_send_space)
|
||||
{
|
||||
list_index_t* pl_index=NULL;
|
||||
stream_send_pane_t *pane=NULL;
|
||||
unsigned int i=0;
|
||||
pl_index=q_get_head(&(reliable_send_space->to_send_queue));
|
||||
while(pl_index!=NULL)
|
||||
{
|
||||
pane=(stream_send_pane_t *)(pl_index->quiddity);
|
||||
free_index_and_data(pane->index_data);
|
||||
pl_index=q_get_head(&(reliable_send_space->to_send_queue));
|
||||
}
|
||||
for(i=0;i<reliable_send_space->resend_times;i++){
|
||||
pl_index=q_get_head(&(reliable_send_space->timeout_queue[i]));
|
||||
while(pl_index!=NULL)
|
||||
{
|
||||
pane=(stream_send_pane_t *)(pl_index->quiddity);
|
||||
free_index_and_data(pane->index_data);
|
||||
pl_index=q_get_head(&(reliable_send_space->timeout_queue[i]));
|
||||
}
|
||||
}
|
||||
_bizman_kernel_hash_destroy(&(reliable_send_space->stream_hash),NULL);
|
||||
}
|
||||
int join_to_reliable_send(reliable_send_space_t*reliable_space,sub_send_task_t* smoothed_task)
|
||||
{
|
||||
send_stream_t* this_stream=NULL;
|
||||
send_data_index_t* index=NULL;
|
||||
|
||||
if(reliable_space->cached_pkts_num_limit!=0&&reliable_space->stat_cached_packet_num>reliable_space->cached_pkts_num_limit)
|
||||
{
|
||||
reliable_space->stat_dropped_pkts_num++;
|
||||
return -1;
|
||||
}
|
||||
if(get_time_tick()-reliable_space->last_expire_time>TIMEOUT_SEND_STREAM_TICK)
|
||||
{
|
||||
expire_send_hash(&(reliable_space->stream_hash));
|
||||
reliable_space->last_expire_time=get_time_tick();
|
||||
}
|
||||
this_stream=find_send_hash(&(reliable_space->stream_hash),smoothed_task->stream_id);
|
||||
if(this_stream==NULL)
|
||||
{
|
||||
this_stream=create_send_stream(smoothed_task,reliable_space->send_widow_size);
|
||||
add_send_hash(&(reliable_space->stream_hash),smoothed_task->stream_id, this_stream);
|
||||
}
|
||||
this_stream->last_edit_tick=get_time_tick();
|
||||
if(this_stream->is_unreachable==TRUE)
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG
|
||||
fprintf(stderr,"stream %d was set unreachable \n",smoothed_task->stream_id);
|
||||
#endif
|
||||
if(this_stream->last_edit_tick-this_stream->forzen_time_stamp>reliable_space->frozen_stream_interval)
|
||||
{
|
||||
this_stream->is_unreachable=FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
reliable_space->stat_frozen_pkts_num++;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
index=create_send_data_index(smoothed_task->refer_index);
|
||||
|
||||
add_data_to_stream(this_stream, index);
|
||||
reliable_space->stat_cached_packet_num++;
|
||||
update_stream_task(reliable_space, this_stream);
|
||||
|
||||
#ifdef BIZMAN_DEBUG
|
||||
for(int i=0;i<reliable_space->resend_times;i++)
|
||||
{
|
||||
if(0>q_list_check(&(reliable_space->timeout_queue[i]), NULL))
|
||||
{
|
||||
fprintf(stderr,"Timeout Queue %d Check Error.\n",i);
|
||||
}
|
||||
}
|
||||
if(0>q_list_check(&(reliable_space->to_send_queue), NULL))
|
||||
{
|
||||
fprintf(stderr,"To send Queue Check Error.\n");
|
||||
}
|
||||
#endif
|
||||
//check expire stream id in hash
|
||||
return 0;
|
||||
}
|
||||
stream_send_pane_t* get_pane_from_timeout(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
stream_send_pane_t* tmp_pane=NULL,*target_pane=NULL;
|
||||
list_index_t* p_list_head=NULL;
|
||||
int i=0;
|
||||
for(i=reliable_space->resend_times-1;i>=0;i--)
|
||||
{
|
||||
p_list_head=q_read_head(&(reliable_space->timeout_queue[i]));
|
||||
if(p_list_head!=NULL)
|
||||
{
|
||||
tmp_pane=(stream_send_pane_t*)(p_list_head->quiddity);
|
||||
if(get_time_tick()-tmp_pane->last_send_time > reliable_space->resend_base_tick*TIMEOUT_RELIABLE_SEND_MULTIPLE[i])
|
||||
{
|
||||
p_list_head=q_get_head(&(reliable_space->timeout_queue[i]));
|
||||
target_pane=(stream_send_pane_t*)(p_list_head->quiddity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target_pane;
|
||||
}
|
||||
void* get_reliable_send_task(reliable_send_space_t*reliable_space,sub_send_task_t*send_task)
|
||||
{
|
||||
stream_send_pane_t* target_pane=NULL;
|
||||
send_stream_t* father_stream=NULL;
|
||||
int flag=0;
|
||||
target_pane=get_pane_from_timeout(reliable_space);
|
||||
if(target_pane==NULL)
|
||||
{
|
||||
target_pane=get_pane_from_to_send(reliable_space);
|
||||
flag++;//for debug
|
||||
}
|
||||
if(target_pane==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
reliable_space->stat_send_packet_count[target_pane->send_times]++;
|
||||
if(target_pane->index_data->refer_index->packet->sequence==START_SEQ_NUM)
|
||||
{
|
||||
if(target_pane->send_times==0)
|
||||
{
|
||||
reliable_space->stat_send_stream_num++;
|
||||
}
|
||||
else if(target_pane->send_times==1)
|
||||
{
|
||||
reliable_space->stat_resend_stream_num++;
|
||||
}
|
||||
}
|
||||
if(target_pane->send_times>=reliable_space->resend_times)
|
||||
{
|
||||
//clear the pane
|
||||
free_index_and_data(target_pane->index_data);
|
||||
target_pane->state=PANE_STATE_SPARE;
|
||||
reliable_space->stat_cached_packet_num--;
|
||||
//then clear the whole stream
|
||||
clear_send_stream(reliable_space, (send_stream_t*)(target_pane->father_stream));
|
||||
//set_unreachable(s);
|
||||
return NULL;
|
||||
}
|
||||
send_task->refer_index=target_pane->index_data->refer_index;
|
||||
send_task->dest_ip=target_pane->dest_ip;
|
||||
send_task->dest_port=target_pane->dest_port;
|
||||
father_stream=(send_stream_t*)(target_pane->father_stream);
|
||||
send_task->stream_id=father_stream->stream_id;
|
||||
return (void*)target_pane;
|
||||
|
||||
}
|
||||
void roll_send_window(reliable_send_space_t* reliable_space,uint32 stream_id,uint32 sequence)
|
||||
{
|
||||
unsigned int i=0;
|
||||
send_stream_t* this_stream=find_send_hash(&(reliable_space->stream_hash),stream_id);
|
||||
|
||||
#ifdef BIZMAN_DEBUG_DETAILS
|
||||
printf("Recv ACK %llu :stream=%d seq=%d\n",get_time_tick(),stream_id,sequence);
|
||||
#endif
|
||||
if(this_stream==NULL)
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG
|
||||
fprintf(stderr,"ACK:unrecognized stream id=%u\n",stream_id);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if(TRUE==this_stream->is_unreachable)
|
||||
{
|
||||
#ifdef BIZMAN_DEBUG
|
||||
fprintf(stderr,"ACK:stream id=%u was set unreachable.\n",stream_id);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if((uint32)this_stream->bigger_sequence<sequence||this_stream->bigger_sequence-sequence>reliable_space->send_widow_size+this_stream->data_queue.listcount)
|
||||
{
|
||||
reliable_space->stat_outwindow_ack++;
|
||||
return;
|
||||
}
|
||||
for(i=0;i<reliable_space->send_widow_size;i++)
|
||||
{
|
||||
if(this_stream->task[i].state==PANE_STATE_TIME_OUT && this_stream->task[i].index_data->refer_index->packet->sequence <= sequence)
|
||||
{
|
||||
q_leave_list(&(reliable_space->timeout_queue[this_stream->task[i].send_times-1]),&(this_stream->task[i].hook) );
|
||||
reuse_stream_pane(reliable_space,&(this_stream->task[i]));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
int handle_ack(reliable_send_space_t*reliable_space,bizman_packet_t* ack_packet){
|
||||
int each_ack_slice=0;
|
||||
uint32 stream_id=0,sequence=0;
|
||||
bizman_slice_t* slice=NULL;
|
||||
reliable_space->stat_ack_pkts_cnt++;
|
||||
if(!(ack_packet->flags&FLAG_ACK_PKT))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(ack_packet->slice_num==0)//old version, unsmoothed ack packet;
|
||||
{
|
||||
roll_send_window(reliable_space,ack_packet->id,ack_packet->sequence);
|
||||
return 0;
|
||||
}
|
||||
slice=(bizman_slice_t*)((char*)ack_packet+LOAD_HEADER_LEN);
|
||||
for(each_ack_slice=0;each_ack_slice<ack_packet->slice_num;each_ack_slice++)
|
||||
{
|
||||
if(slice->slice_len!=sizeof(uint32)*2+SLICE_HEADER_LEN)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
stream_id=*(uint32*)((char*)slice+SLICE_HEADER_LEN);
|
||||
sequence=*(uint32*)((char*)slice+SLICE_HEADER_LEN+sizeof(uint32));
|
||||
slice=(bizman_slice_t* )((char*)slice+slice->slice_len);
|
||||
|
||||
roll_send_window(reliable_space,stream_id,sequence);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void recycle_transition_handle(reliable_send_space_t*reliable_space,void *p){
|
||||
stream_send_pane_t* tmp_pane=(stream_send_pane_t*)p;
|
||||
#ifdef BIZMAN_DEBUG_DETAILS
|
||||
printf("Send DAT %llu:stream=%d seq=%d\n",get_time_tick(),tmp_pane->index_data->refer_index->packet->id,tmp_pane->index_data->refer_index->packet->sequence);
|
||||
#endif
|
||||
if(tmp_pane->is_relaible==FALSE)
|
||||
{
|
||||
|
||||
reuse_stream_pane(reliable_space,tmp_pane);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout_stream_pane(reliable_space,tmp_pane);
|
||||
}
|
||||
}
|
||||
int set_send_cached_pkts_limit(reliable_send_space_t*reliable_space,unsigned long long max_cached)
|
||||
{
|
||||
reliable_space->cached_pkts_num_limit=max_cached;
|
||||
return 1;
|
||||
}
|
||||
unsigned long long stat_first_resend_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_send_packet_count[1];
|
||||
}
|
||||
unsigned long long stat_first_send_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_send_packet_count[0];
|
||||
}
|
||||
unsigned long long stat_last_resend_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_send_packet_count[reliable_space->resend_times];
|
||||
}
|
||||
unsigned long long stat_dropped_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_dropped_pkts_num;
|
||||
}
|
||||
unsigned long long stat_frozen_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_frozen_pkts_num;
|
||||
}
|
||||
unsigned long long stat_ack_packet_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_ack_pkts_cnt;
|
||||
}
|
||||
unsigned long long stat_frist_send_stream_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_send_stream_num;
|
||||
}
|
||||
unsigned long long stat_frist_resend_stream_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stat_resend_stream_num;
|
||||
}
|
||||
unsigned long long stat_active_stream_count(reliable_send_space_t*reliable_space)
|
||||
{
|
||||
return reliable_space->stream_hash.elem_count;
|
||||
}
|
||||
|
||||
92
src/support/Businessman/reliable_send.h
Normal file
92
src/support/Businessman/reliable_send.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef _BIZMAN_RELIABLE_SEND_H_INCLUDE_
|
||||
#define _BIZMAN_RELIABLE_SEND_H_INCLUDE_
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_packet.h"
|
||||
#include "businessman_base.h"
|
||||
#include "businessman_limit.h"
|
||||
//const unsigned int TIMEOUT_QUEUE_NUM=MAX_RESEND_TIMES;
|
||||
enum PANE_STATE
|
||||
{
|
||||
PANE_STATE_SPARE=0,
|
||||
PANE_STATE_WAIT_SEND,
|
||||
PANE_STATE_TIME_OUT
|
||||
};
|
||||
|
||||
typedef struct _businessman_send_pane_t{
|
||||
int order;
|
||||
uint32 dest_ip;
|
||||
uint16 dest_port;
|
||||
int is_relaible;
|
||||
time_tick_t last_send_time;
|
||||
unsigned int send_times;
|
||||
void* father_stream;
|
||||
send_data_index_t* index_data;
|
||||
PANE_STATE state;
|
||||
list_index_t hook;
|
||||
}stream_send_pane_t;
|
||||
typedef struct _businessman_send_stream_t{
|
||||
unsigned int stream_id;
|
||||
uint32 dest_ip;
|
||||
uint16 dest_port;
|
||||
int is_relaible;
|
||||
queue_head_t data_queue;
|
||||
unsigned int in_use_task_num;
|
||||
uint32 bigger_sequence; //grow when new data joined,new data use this as its sequence
|
||||
stream_send_pane_t *task;
|
||||
// list_index_t hook;
|
||||
time_tick_t last_edit_tick;
|
||||
unsigned int is_unreachable;//destination unreachable;
|
||||
time_tick_t forzen_time_stamp;
|
||||
unsigned int send_window_size;
|
||||
}send_stream_t;
|
||||
typedef struct _bizman_reliable_send_space_t{
|
||||
hash_tab_t stream_hash;
|
||||
queue_head_t to_send_queue;
|
||||
queue_head_t timeout_queue[MAX_RESEND_TIMES];
|
||||
time_tick_t last_expire_time;
|
||||
unsigned long long stat_send_packet_count[MAX_RESEND_TIMES+1];
|
||||
unsigned long long stat_outwindow_ack;
|
||||
unsigned long long stat_ack_pkts_cnt;
|
||||
unsigned long long stat_cached_packet_num;
|
||||
unsigned long long cached_pkts_num_limit;
|
||||
unsigned long long stat_dropped_pkts_num;
|
||||
unsigned long long stat_frozen_pkts_num;
|
||||
unsigned long long stat_send_stream_num;
|
||||
unsigned long long stat_resend_stream_num;
|
||||
//parameter
|
||||
unsigned int send_widow_size;
|
||||
unsigned int resend_times;
|
||||
time_tick_t resend_base_tick;
|
||||
time_tick_t frozen_stream_interval;
|
||||
|
||||
|
||||
}reliable_send_space_t;
|
||||
|
||||
|
||||
reliable_send_space_t* create_reliable_send_space();
|
||||
void destroy_reliable_send_space(reliable_send_space_t* reliable_send_space);
|
||||
/*return 0 when success,return -1 when failed*/
|
||||
int join_to_reliable_send(reliable_send_space_t*reliable_space,sub_send_task_t* smoothed_task);
|
||||
|
||||
/*return a transition handle(not null) when success ,return NULL when failed*/
|
||||
void *get_reliable_send_task(reliable_send_space_t*reliable_space,sub_send_task_t*send_task);
|
||||
|
||||
void recycle_transition_handle(reliable_send_space_t*reliable_space,void *p);
|
||||
/*handle a received ack;return 0 when success,return -1 when failed*/
|
||||
int handle_ack(reliable_send_space_t*reliable_space,bizman_packet_t* ack_packet);
|
||||
unsigned long long stat_first_resend_packet_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_first_send_packet_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_last_resend_packet_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_dropped_packet_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_frozen_packet_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_frist_send_stream_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_frist_resend_stream_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_active_stream_count(reliable_send_space_t*reliable_space);
|
||||
unsigned long long stat_ack_packet_count(reliable_send_space_t*reliable_space);
|
||||
|
||||
int set_send_cached_pkts_limit(reliable_send_space_t*reliable_space,unsigned long long max_cached);
|
||||
#endif //_BIZMAN_RELIABLE_SEND_H_INCLUDE_
|
||||
|
||||
|
||||
397
src/support/Businessman/smooth_send.cpp
Normal file
397
src/support/Businessman/smooth_send.cpp
Normal file
@@ -0,0 +1,397 @@
|
||||
/***************************************************
|
||||
*Businessman Data Exchange System Smooth Layer Implement
|
||||
*Author :zhengchao@iie.ac.cn
|
||||
*This program cache and smooth the user app's send data;
|
||||
*Else it will cache for a while to wait more data pieces.
|
||||
****************************************************/
|
||||
#include <math.h>//ceil
|
||||
#include "businessman_error.h"
|
||||
#include "businessman_limit.h"
|
||||
#include "businessman_time.h"
|
||||
#include "businessman_memory.h"
|
||||
#include "businessman_packet.h"
|
||||
#include "bizman.h"
|
||||
#include "smooth_send.h"
|
||||
|
||||
const time_tick_t TIMEOUT_SMOOTH_STREAM_TICK=TIMEOUT_SMOOTH_STREAM_USEC/TIME_TICK_STEP_USEC;
|
||||
|
||||
const unsigned int SMOOTH_HASH_SIZE=1024*8;
|
||||
|
||||
void free_stream_data(void*p)
|
||||
{
|
||||
smooth_stream_t *p_stream=(smooth_stream_t *)p;
|
||||
free(p_stream->sub_stream_id);
|
||||
free(p_stream->dest_ip);
|
||||
free(p_stream->dest_port);
|
||||
p_stream->smooth_block=NULL;//block is in timeout queue,need not to free
|
||||
free(p);
|
||||
}
|
||||
void make_key( unsigned char *key,uint64 app_id,char is_reliable)
|
||||
{
|
||||
|
||||
memcpy(key,(char*)(&app_id),sizeof(app_id));
|
||||
memcpy(key+sizeof(app_id),&is_reliable,sizeof(is_reliable));
|
||||
}
|
||||
int smooth_hash_expire(void*p)
|
||||
{
|
||||
smooth_stream_t *p_stream=(smooth_stream_t *)p;
|
||||
if(get_time_tick()-p_stream->last_edit_tick >TIMEOUT_SMOOTH_STREAM_TICK && p_stream->active_block_num==0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int create_smooth_hash(hash_tab_t *stream_table)
|
||||
{
|
||||
return _bizman_kernel_hash_create(stream_table, SMOOTH_HASH_SIZE ,NULL,NULL, smooth_hash_expire, free_stream_data);
|
||||
}
|
||||
int destroy_smooth_hash(hash_tab_t *stream_table)
|
||||
{
|
||||
return _bizman_kernel_hash_destroy(stream_table, NULL);
|
||||
}
|
||||
smooth_stream_t* find_smooth_hash(hash_tab_t*stream_table,uint64 app_id,char is_reliable)
|
||||
{
|
||||
unsigned char key[9];//8+1
|
||||
make_key(key, app_id, is_reliable);
|
||||
return (smooth_stream_t*)_bizman_kernel_hash_sel(stream_table, key,sizeof(key));
|
||||
}
|
||||
int add_smooth_hash(hash_tab_t*stream_table,uint64 app_id,char is_reliable,smooth_stream_t* data)
|
||||
{
|
||||
unsigned char key[9];//8+1
|
||||
make_key(key, app_id, is_reliable);
|
||||
return _bizman_kernel_hash_add(stream_table, key, sizeof(key), (void *)data);
|
||||
}
|
||||
int delete_smooth_hash(hash_tab_t*stream_table,uint64 app_id,char is_reliable)
|
||||
{
|
||||
unsigned char key[9];//8+1
|
||||
make_key(key, app_id, is_reliable);
|
||||
return _bizman_kernel_hash_del(stream_table, key, sizeof(key),NULL);
|
||||
}
|
||||
int expire_smooth_hash(hash_tab_t*stream_table)
|
||||
{
|
||||
return _bizman_kernel_hash_expire(stream_table);
|
||||
}
|
||||
smooth_space_t* create_smooth_send_space(){
|
||||
smooth_space_t* smooth_space=NULL;
|
||||
smooth_space=(smooth_space_t*)b_malloc(sizeof(smooth_space_t));
|
||||
if(NULL==smooth_space)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(smooth_space,0,sizeof(smooth_space_t));
|
||||
create_smooth_hash(&(smooth_space->stream_hash));
|
||||
bizman_init_lock(&(smooth_space->thread_lock));
|
||||
smooth_space->last_expire_time=get_time_tick();
|
||||
smooth_space->smooth_timeout_tick=DEFAULT_TIMEOUT_SMOOTH_BLOCK_USEC/TIME_TICK_STEP_USEC;
|
||||
smooth_space->stat_dropped_pkts_num=0;
|
||||
smooth_space->cache_smooth_pkts_limit=0;
|
||||
return smooth_space;
|
||||
}
|
||||
void destroy_smooth_send_space(smooth_space_t* thread_smooth_space)
|
||||
{
|
||||
list_index_t *pl_index=NULL;
|
||||
smooth_block_t* block=NULL;
|
||||
//free smooth ready queue
|
||||
pl_index=q_get_head(&(thread_smooth_space->smooth_ready_queue));
|
||||
while(pl_index!=NULL)
|
||||
{
|
||||
block=(smooth_block_t*)(pl_index->quiddity);
|
||||
free(block->buff);
|
||||
free(block);
|
||||
pl_index=q_get_head(&(thread_smooth_space->smooth_ready_queue));
|
||||
}
|
||||
//free timeout
|
||||
pl_index=q_get_head(&(thread_smooth_space->smooth_timeout_queue));
|
||||
while(pl_index!=NULL)
|
||||
{
|
||||
block=(smooth_block_t*)(pl_index->quiddity);
|
||||
free(block->buff);
|
||||
free(block);
|
||||
pl_index=q_get_head(&(thread_smooth_space->smooth_timeout_queue));
|
||||
}
|
||||
//free smooth hash;
|
||||
_bizman_kernel_hash_destroy(&(thread_smooth_space->stream_hash), NULL);
|
||||
free(thread_smooth_space);
|
||||
|
||||
}
|
||||
smooth_block_t* create_smooth_block(const smooth_stream_t* smooth_stream){
|
||||
smooth_block_t* new_block=NULL;
|
||||
bizman_packet_t* p_pkt=NULL;
|
||||
new_block=(smooth_block_t *)b_malloc(sizeof(smooth_block_t));
|
||||
new_block->buff=(char*)b_malloc(MTU_SIZE);
|
||||
new_block->buff_size=MTU_SIZE;
|
||||
new_block->used_size=LOAD_HEADER_LEN;
|
||||
new_block->hook.quiddity=(void *)new_block;
|
||||
new_block->first_filled_tick=get_time_tick();
|
||||
|
||||
new_block->father_stream=(void*)smooth_stream;
|
||||
p_pkt=(bizman_packet_t *)new_block->buff;
|
||||
init_packet(p_pkt,smooth_stream->is_reliable,smooth_stream->stream_id,LOAD_HEADER_LEN);
|
||||
#ifdef DEPLOY_YSP_SYSTEM
|
||||
memcpy(&(p_pkt->app_id),&(smooth_stream->app_id),sizeof(p_pkt->app_id));
|
||||
#endif
|
||||
if(smooth_stream->is_reliable==TRUE)
|
||||
{
|
||||
new_block->is_reliable=TRUE;
|
||||
}
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
smooth_stream_t* create_smooth_stream(const external_send_task_t *send_task){
|
||||
unsigned int i=0;
|
||||
smooth_stream_t* new_stream=NULL;
|
||||
new_stream=(smooth_stream_t*)b_malloc(sizeof(smooth_stream_t));
|
||||
new_stream->stream_id=generate_stream_id();
|
||||
new_stream->sub_stream_id=(unsigned int*)b_malloc(send_task->dest_num*sizeof(new_stream->stream_id));
|
||||
new_stream->sub_stream_id[0]=new_stream->stream_id;
|
||||
for(i=1;i<send_task->dest_num;i++)
|
||||
{
|
||||
new_stream->sub_stream_id[i]=generate_stream_id();
|
||||
}
|
||||
new_stream->app_id=send_task->app_id;
|
||||
new_stream->dest_num=send_task->dest_num;
|
||||
new_stream->dest_ip=(unsigned int*)b_malloc(send_task->dest_num*sizeof(*(new_stream->dest_ip)));
|
||||
memcpy(new_stream->dest_ip,send_task->dest_ip,send_task->dest_num*sizeof(*(new_stream->dest_ip)));
|
||||
new_stream->dest_port=(unsigned short*)b_malloc(send_task->dest_num*sizeof(*(new_stream->dest_port)));
|
||||
memcpy(new_stream->dest_port,send_task->dest_port,send_task->dest_num*sizeof(*(new_stream->dest_port)));
|
||||
if(send_task->flags&FLAG_NEED_ACK)
|
||||
{
|
||||
new_stream->is_reliable=TRUE;
|
||||
}
|
||||
new_stream->active_block_num=0;
|
||||
return new_stream;
|
||||
}
|
||||
|
||||
void make_stream_block_ready(smooth_space_t* smooth_space,smooth_stream_t * target_stream)
|
||||
{
|
||||
smooth_block_t*target_block=target_stream->smooth_block;
|
||||
|
||||
if(0<q_is_item_in_list_quick(&(smooth_space->smooth_timeout_queue), &(target_block->hook)))//only block in timeout queue could put in to
|
||||
{
|
||||
q_leave_list(&(smooth_space->smooth_timeout_queue), &(target_block->hook));
|
||||
q_join_tail(&(smooth_space->smooth_ready_queue), &(target_block->hook));
|
||||
target_stream->smooth_block=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
;//error occured
|
||||
}
|
||||
}
|
||||
void make_stream_block_timeout(smooth_space_t* smooth_space,smooth_stream_t* target_stream)
|
||||
{
|
||||
smooth_block_t*target_block=target_stream->smooth_block;
|
||||
if(target_block->hook.nextele==NULL&&target_block->hook.preele==NULL)//only unindexed block could put in to
|
||||
{
|
||||
q_join_tail(&(smooth_space->smooth_timeout_queue), &(target_block->hook));
|
||||
target_stream->active_block_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
;//error occured
|
||||
}
|
||||
}
|
||||
smooth_block_t* get_smooth_timeout_block(smooth_space_t* smooth_space)
|
||||
{
|
||||
queue_head_t *time_out_queue=&(smooth_space->smooth_timeout_queue);
|
||||
list_index_t* tmp_list_index=NULL;
|
||||
smooth_block_t* target_block=NULL;
|
||||
smooth_stream_t* father_stream=NULL;
|
||||
smooth_block_t* timeout_wait_block=NULL;
|
||||
tmp_list_index=q_read_head(time_out_queue);
|
||||
if(NULL==tmp_list_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
timeout_wait_block=(smooth_block_t*)(tmp_list_index->quiddity);
|
||||
if(get_time_tick()-timeout_wait_block->first_filled_tick>smooth_space->smooth_timeout_tick)
|
||||
{
|
||||
tmp_list_index=q_get_head(&(smooth_space->smooth_timeout_queue));
|
||||
if(tmp_list_index!=NULL)
|
||||
{
|
||||
target_block=(smooth_block_t*)(tmp_list_index->quiddity);
|
||||
father_stream=(smooth_stream_t*)(target_block->father_stream);
|
||||
father_stream->smooth_block=NULL;
|
||||
return target_block;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
smooth_block_t* get_smooth_ready_block(smooth_space_t* smooth_space)
|
||||
{
|
||||
list_index_t* target_list_index=NULL;
|
||||
smooth_block_t* target_block=NULL;
|
||||
|
||||
|
||||
target_list_index=q_get_head(&(smooth_space->smooth_ready_queue));
|
||||
if(target_list_index!=NULL)
|
||||
{
|
||||
target_block=(smooth_block_t*)(target_list_index->quiddity);
|
||||
return target_block;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/**/
|
||||
void remove_stream(smooth_space_t* smooth_space,smooth_stream_t* target_stream)
|
||||
{
|
||||
if(target_stream->smooth_block!=NULL)
|
||||
{
|
||||
make_stream_block_ready(smooth_space, target_stream);
|
||||
}
|
||||
delete_smooth_hash(&(smooth_space->stream_hash), target_stream->app_id, target_stream->is_reliable);
|
||||
}
|
||||
/*return len write*/
|
||||
int add_slice_to_block(smooth_block_t *block,const char* data,int len,unsigned int offset){
|
||||
|
||||
|
||||
int empty_space_len=block->buff_size-block->used_size;
|
||||
int write_len=MIN((int)(len+SLICE_HEADER_LEN),empty_space_len)-SLICE_HEADER_LEN;
|
||||
bizman_packet_t* p_pkt=(bizman_packet_t*)(block->buff);
|
||||
bizman_slice_t*p_slice=(bizman_slice_t*)(block->buff+block->used_size);
|
||||
char* p_slice_data=(char*)p_slice+SLICE_HEADER_LEN;
|
||||
if(block->buff_size-block->used_size <= SLICE_HEADER_LEN){
|
||||
return 0;
|
||||
}
|
||||
if(p_pkt->slice_num==MTU_SIZE/(SLICE_HEADER_LEN+sizeof(uint32)*2))//avoid 8 bytes ack fragment;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(p_slice_data,data,write_len);
|
||||
|
||||
p_slice->slice_len=write_len+SLICE_HEADER_LEN;
|
||||
// p_slice->offset=offset;
|
||||
if(write_len==len)
|
||||
{
|
||||
p_slice->flags=SLICE_LAST_FRAG;
|
||||
}
|
||||
p_pkt->slice_num++;
|
||||
p_pkt->len+=p_slice->slice_len;
|
||||
|
||||
block->used_size+=p_slice->slice_len;
|
||||
return write_len;
|
||||
}
|
||||
|
||||
int smooth_block(smooth_space_t * thread_smooth_space,const external_send_task_t *send_task)
|
||||
{
|
||||
smooth_stream_t* this_stream=NULL;
|
||||
int len=send_task->len;
|
||||
int write_len_ret=0,already_written_len=0;
|
||||
const char* data=send_task->data;
|
||||
char is_reliable=FALSE;
|
||||
if(send_task->flags&FLAG_NEED_ACK)
|
||||
{
|
||||
is_reliable=TRUE;
|
||||
}
|
||||
bizman_lock(&(thread_smooth_space->thread_lock));
|
||||
if(thread_smooth_space->cache_smooth_pkts_limit>0 &&
|
||||
thread_smooth_space->smooth_ready_queue.listcount+thread_smooth_space->smooth_timeout_queue.listcount >thread_smooth_space->cache_smooth_pkts_limit)
|
||||
{
|
||||
thread_smooth_space->stat_dropped_pkts_num++;
|
||||
bizman_unlock(&(thread_smooth_space->thread_lock));
|
||||
return -1;
|
||||
}
|
||||
if(get_time_tick()-thread_smooth_space->last_expire_time>TIMEOUT_SMOOTH_STREAM_TICK)
|
||||
{
|
||||
expire_smooth_hash(&(thread_smooth_space->stream_hash));
|
||||
thread_smooth_space->last_expire_time=get_time_tick();
|
||||
}
|
||||
this_stream=find_smooth_hash(&(thread_smooth_space->stream_hash),send_task->app_id,is_reliable);
|
||||
|
||||
//new stream id to current thread
|
||||
if(NULL==this_stream)
|
||||
{
|
||||
this_stream=create_smooth_stream(send_task);
|
||||
add_smooth_hash(&(thread_smooth_space->stream_hash), send_task->app_id,is_reliable ,this_stream);
|
||||
}
|
||||
|
||||
this_stream->last_edit_tick=get_time_tick();
|
||||
if(this_stream->smooth_block==NULL)
|
||||
{
|
||||
this_stream->smooth_block=create_smooth_block(this_stream);
|
||||
make_stream_block_timeout(thread_smooth_space, this_stream);
|
||||
}
|
||||
|
||||
while(already_written_len<len)
|
||||
{
|
||||
write_len_ret=add_slice_to_block(this_stream->smooth_block, data+already_written_len,len-already_written_len, this_stream->already_smoothed_bytes);
|
||||
if(write_len_ret>0)
|
||||
{
|
||||
already_written_len+=write_len_ret;
|
||||
this_stream->already_smoothed_bytes+=write_len_ret;
|
||||
}
|
||||
else //block is full
|
||||
{
|
||||
make_stream_block_ready(thread_smooth_space,this_stream);
|
||||
this_stream->smooth_block=create_smooth_block(this_stream);
|
||||
make_stream_block_timeout(thread_smooth_space, this_stream);
|
||||
}
|
||||
}
|
||||
if(send_task->flags&FLAG_LAST_PKT)
|
||||
{
|
||||
set_packet_flag_last((bizman_packet_t*)(this_stream->smooth_block->buff));
|
||||
make_stream_block_ready(thread_smooth_space,this_stream);
|
||||
remove_stream(thread_smooth_space, this_stream);
|
||||
}
|
||||
else if(send_task->flags&BIZMAN_PUSH_SEND)
|
||||
{
|
||||
make_stream_block_ready(thread_smooth_space,this_stream);
|
||||
}
|
||||
bizman_unlock(&(thread_smooth_space->thread_lock));
|
||||
return 0;
|
||||
}
|
||||
int get_smoothed_task(smooth_space_t * thread_smooth_space,internal_send_task_t * task)
|
||||
{
|
||||
smooth_block_t* target=NULL;
|
||||
smooth_stream_t* father_stream=NULL;
|
||||
if(NULL==task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bizman_lock(&(thread_smooth_space->thread_lock));
|
||||
|
||||
target=get_smooth_ready_block(thread_smooth_space);
|
||||
if(target==NULL)
|
||||
{
|
||||
target=get_smooth_timeout_block(thread_smooth_space);
|
||||
}
|
||||
|
||||
bizman_unlock(&(thread_smooth_space->thread_lock));
|
||||
|
||||
if(target==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bizman_lock(&(thread_smooth_space->thread_lock));
|
||||
father_stream=(smooth_stream_t*)target->father_stream;
|
||||
task->stream_id=father_stream->stream_id;
|
||||
|
||||
|
||||
task->dest_num=father_stream->dest_num;
|
||||
task->dest_ip=(unsigned int*)b_malloc(father_stream->dest_num*sizeof(*(task->dest_ip)));
|
||||
memcpy(task->dest_ip,father_stream->dest_ip,father_stream->dest_num*sizeof(*(task->dest_ip)));
|
||||
task->dest_port=(unsigned short*)b_malloc(father_stream->dest_num*sizeof(*(father_stream->dest_port)));
|
||||
memcpy(task->dest_port,father_stream->dest_port,father_stream->dest_num*sizeof(*(task->dest_port)));
|
||||
task->sub_stream_id=(unsigned int*)b_malloc(father_stream->dest_num*sizeof(*(father_stream->sub_stream_id)));
|
||||
memcpy(task->sub_stream_id,father_stream->sub_stream_id,father_stream->dest_num*sizeof(*(father_stream->sub_stream_id)));
|
||||
|
||||
task->data=create_send_data_refer(target->buff, target->used_size, task->dest_num);
|
||||
task->is_reliable=target->is_reliable;
|
||||
|
||||
father_stream->active_block_num--;
|
||||
bizman_unlock(&(thread_smooth_space->thread_lock));
|
||||
|
||||
free(target);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user