20180929 first commit

This commit is contained in:
lishu
2018-09-29 14:57:32 +08:00
commit 19cfcaf353
1283 changed files with 2427387 additions and 0 deletions

224
src/AV_interface.h Normal file
View 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>
#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>
#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
View 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>
//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
View 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>
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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

35
src/frag_av.h Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

42
src/frag_proc.h Normal file
View 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

File diff suppressed because it is too large Load Diff

70
src/frag_reassembly.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

156
src/frag_voip.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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

Binary file not shown.

BIN
src/lib/lib_MESA_timer.a Normal file

Binary file not shown.

Binary file not shown.

BIN
src/lib/libbusinessman.a Normal file

Binary file not shown.

BIN
src/lib/libdictator_debug.a Normal file

Binary file not shown.

BIN
src/lib/libhiredis_vip.a Normal file

Binary file not shown.

BIN
src/lib/libmy_socket.a Normal file

Binary file not shown.

BIN
src/lib/libsifter.a Normal file

Binary file not shown.

BIN
src/lib/usm_comm.a Normal file

Binary file not shown.

484
src/log.c Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

289
src/main.h Normal file
View 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

File diff suppressed because it is too large Load Diff

35
src/message.h Normal file
View 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
View 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
View 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

View 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)

View 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

View 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_

View 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;
}

View 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;

View 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;
}

View 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_

View 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_*/

View 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_

View 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

View 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;
}

View 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_*/

View 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(&current_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;
}
}

View 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_

View 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;
}

View 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_ */

Binary file not shown.

Binary file not shown.

View 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;
}

View 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 */

View 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;
}

View 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_

View 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;
}

View 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_

View 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;
}

View 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_

View 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