diff options
| author | 刘学利 <[email protected]> | 2023-02-28 03:17:18 +0000 |
|---|---|---|
| committer | 刘学利 <[email protected]> | 2023-02-28 03:17:18 +0000 |
| commit | e9974578ead7c7cb9f0c7e758e24c7e7b9b2aeac (patch) | |
| tree | 94d23f992619aa3ca8b356a8aba39e09d0aad367 /src/dealpkt/plug_support.c | |
| parent | 35ae368647c22ec75ae7034b6f8c29af4f40351e (diff) | |
overlay为NF模式下,无条件转发数据包,并携带SID、流ID等
Diffstat (limited to 'src/dealpkt/plug_support.c')
| -rw-r--r-- | src/dealpkt/plug_support.c | 3924 |
1 files changed, 1967 insertions, 1957 deletions
diff --git a/src/dealpkt/plug_support.c b/src/dealpkt/plug_support.c index becb683..4ec1bbc 100644 --- a/src/dealpkt/plug_support.c +++ b/src/dealpkt/plug_support.c @@ -1,1957 +1,1967 @@ -/* - ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���, - ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��, -*/ -#include "sapp_api.h" -#include "sapp_private_api.h" -#include "sapp_declaration.h" -#include "stream_inc/stream_base.h" -#include "stream_inc/stream_rawpkt.h" - -#ifdef __cplusplus -extern "C" { -#endif -extern int G_TCP_FLOW_STAT_PROJECT_ID ; -extern int G_UDP_FLOW_STAT_PROJECT_ID ; - - -extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream); -#if IOMODE_MARSIO -extern void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id); -#endif - - -struct detain_pkt* MESA_rawpkt_detain(const struct streaminfo *pstream, const void *rawpkt) -{ - if(pstream == NULL || rawpkt == NULL)return NULL; - - raw_pkt_t *p_rawpkt = (raw_pkt_t *)rawpkt; - assert(p_rawpkt->magic_num == RAW_PKT_MAGIC_NUM); - if(p_rawpkt->magic_num != RAW_PKT_MAGIC_NUM )return NULL; - - if(p_rawpkt->d_pkt)return NULL; // rawpkt can be retained only once - if(p_rawpkt->drop_current_pkt_flag == 1)return NULL; // rawpkt need to be drop, can not be retained - - if(sapp_global_val->config.packet_io.depolyment_mode_bin != DEPOLYMENT_MODE_INLINE)return NULL; - - struct detain_pkt *d_pkt = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(struct detain_pkt)); - d_pkt->original = rawpkt; - memcpy(&d_pkt->replica, p_rawpkt, sizeof(raw_pkt_t)); - d_pkt->replica.append_list=NULL; - d_pkt->replica.prepend_list=NULL; - if(p_rawpkt->append_list!= NULL && p_rawpkt->append_list->sz_sidlist > 0) - { - d_pkt->replica.append_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist); - memcpy(d_pkt->replica.append_list->sid_list, p_rawpkt->append_list->sid_list, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist); - d_pkt->replica.append_list->sz_sidlist = p_rawpkt->append_list->sz_sidlist; - } - if(p_rawpkt->prepend_list!= NULL && p_rawpkt->prepend_list->sz_sidlist > 0) - { - d_pkt->replica.prepend_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist); - memcpy(d_pkt->replica.prepend_list->sid_list, p_rawpkt->prepend_list->sid_list, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist); - d_pkt->replica.prepend_list->sz_sidlist = p_rawpkt->prepend_list->sz_sidlist; - } - p_rawpkt->d_pkt = d_pkt; - d_pkt->tid = pstream->threadnum; - - return d_pkt; -} - -static void detain_pkt_mem_free(struct detain_pkt *pkt) -{ - if(pkt == NULL)return; - if(pkt->replica.append_list) - { - sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.append_list); - } - if(pkt->replica.prepend_list) - { - sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.prepend_list); - } - sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt); -} - -int MESA_detain_pkt_forward(struct detain_pkt *pkt) -{ - if(pkt->original == NULL) //original packet stack finished, being processed by all plugin; - { - if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference) - { - dl_io_fun_list.dl_io_forward_rawpkt(&pkt->replica, pkt->tid); - } - detain_pkt_mem_free(pkt); - pkt = NULL; - } - else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica; - { - if(pkt->mark != RETAIN_RAWPKT) - { - return -1; // redundant operation, return abnormal - } - pkt->mark = FORWARD_RAWPKT; - } - return 0; -} - -void MESA_detain_pkt_free(struct detain_pkt *pkt) -{ - if(pkt->original == NULL) //original packet stack finished, being processed by all plugin; - { - if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference) - { - dl_io_fun_list.dl_io_free_rawpkt(&pkt->replica, pkt->tid); - } - detain_pkt_mem_free(pkt); - pkt = NULL; - - } - else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica; - { - if(pkt->mark == RETAIN_RAWPKT) - { - pkt->mark = FREE_RAWPKT; - } - } -} - -int MESA_retain_pkt_update(const raw_pkt_t *p_raw_pkt, int pkt_ret) -{ - int update_ret = pkt_ret; - - assert(p_raw_pkt->magic_num == RAW_PKT_MAGIC_NUM); - if(p_raw_pkt->magic_num != RAW_PKT_MAGIC_NUM )return pkt_ret; - - if (p_raw_pkt->d_pkt != NULL)// have retain operation - { - if (p_raw_pkt->d_pkt->mark == RETAIN_RAWPKT) //retain pkt in use - { - if (pkt_ret == PASS) - { - update_ret = RETAIN; - } - if (pkt_ret == DROP) - { - p_raw_pkt->d_pkt->replica.io_lib_pkt_reference = NULL; - p_raw_pkt->d_pkt->replica.__lib_raw_pkt_data = NULL; - p_raw_pkt->d_pkt->replica.__lib_raw_pkt_len = 0; - } - p_raw_pkt->d_pkt->original = NULL; - } - else //During the processing of the original package, the retained pkt being called forward or free, so it is directly released - { - if (p_raw_pkt->d_pkt->mark == FREE_RAWPKT) - { - update_ret = DROP; - } - detain_pkt_mem_free(p_raw_pkt->d_pkt); - } - } - return update_ret; -} - -int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value) -{ - int ret = 0; - const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt; - - if(NULL == voidpkt || NULL == void_value){ - return -1; - } - - if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ���� */ - return -1; - } - - switch(type){ - case RAW_PKT_GET_DATA: - { - void **out_value = (void **)void_value; - *out_value = (char *)rawpkt->raw_pkt_data + rawpkt->overlay_layer_bytes; - } - break; - - case RAW_PKT_GET_RAW_PKT_TYPE: - { - enum addr_type_t *out_value = (enum addr_type_t *)void_value; - *out_value = rawpkt->low_layer_type; - } - break; - - case RAW_PKT_GET_TOT_LEN: - { - int *out_value = (int *)void_value; - *out_value = rawpkt->raw_pkt_len - rawpkt->overlay_layer_bytes; - } - break; - - case RAW_PKT_GET_TIMESTAMP: - { - struct timeval *out_value =(struct timeval *)void_value; - memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval)); - } - break; - - case RAW_PKT_GET_THIS_LAYER_HDR: - { - void **out_value = (void **)void_value; - const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr; - *out_value = (void *)this_layer_hdr; - } - break; - - case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN: - { - int *out_value = (int *)void_value; - *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr; - } - break; - - case RAW_PKT_GET_VIRTUAL_LINK_ID: - { - /* from sapp v4.2, there is no mrtunnat module, so not support this option! */ - sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_VIRTUAL_LINK_ID' in sappv4.2 and later!"); - ret = -1; - } - break; - - case RAW_PKT_GET_REHASH_INDEX: - { - /* from sapp v4.2, there is no mrtunnat module, so not support this option! */ - sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_REHASH_INDEX' in sappv4.2 and later!"); - ret = -1; - } - break; - - - /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */ - case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC: - { - const struct mesa_ethernet_hdr *lowest_ehdr; - - if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat - if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){ - if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){ - const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ - if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */ - ret = -1; - }else{ - memcpy(void_value, mr_ctrlzone->g_device_mac, ETH_ALEN); - } - }else{ - sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!"); - ret = -1; - } - }else{ - lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN); - } - }else{ //from v4.2, without mrtunnat - lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN); - } - } - break; - - /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */ - case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC: - { - const struct mesa_ethernet_hdr *lowest_ehdr; - - if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat - if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){ - if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){ - const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ - if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */ - ret = -1; - }else{ - memcpy(void_value, mr_ctrlzone->l_device_mac, ETH_ALEN); - } - }else{ - sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!"); - ret = -1; - } - }else{ - lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN); - } - }else{ //from v4.2, without mrtunnat - lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN); - } - } - break; - - default: - sapp_runtime_log(RLOG_LV_FATAL, "get_opt_from_rawpkt(): not support option type: %d", type); - ret = -1; - break; - } - - return ret; -} - - - -static const struct streaminfo_private *offset_to_vxlan_layer(const struct streaminfo_private *pstream_pr) -{ - while(pstream_pr && (ADDR_TYPE_VXLAN != pstream_pr->stream_public.addr.addrtype)){ - pstream_pr = pstream_pr->pfather_pr; - } - - return pstream_pr; -} - - -static int get_vxlan_info_from_streaminfo(const struct streaminfo_private *pstream_pr, int type, void *void_value) -{ - int ret = 0; - const struct streaminfo_private *vxlan_pstream_pr; - const raw_pkt_t *rawpkt; - const inline_vxlan_hdr_t *p_vxlan_hdr; - - if(DEPOLYMENT_MODE_INLINE != g_topology_mode_raw){ - sapp_runtime_log(RLOG_LV_INFO, "get_rawpkt_opt_from_streaminfo() error: can't support option type: %d in no inline mode!", type); - return -1; - } - - vxlan_pstream_pr = offset_to_vxlan_layer(pstream_pr); - if(NULL == vxlan_pstream_pr){ - sapp_runtime_log(RLOG_LV_FATAL, "get_rawpkt_opt_from_streaminfo() error, stream:%s not found vxlan layer!", - printaddr(&pstream_pr->stream_public.addr, pstream_pr->stream_public.threadnum)); - return -1; - } - - rawpkt = pstream_pr->raw_pkt; - p_vxlan_hdr = (inline_vxlan_hdr_t *)((char *)rawpkt->raw_pkt_data + vxlan_pstream_pr->offset_to_raw_pkt_hdr); - - switch(type){ - case RAW_PKT_GET_GDEV_IP: - { - const struct mesa_ip4_hdr *pip4_hdr; - const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr; - if(NULL == carry_vxlan_ip_layer){ - return -1; - } - - pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr); - int *out_value = (int *)void_value; - *out_value = pip4_hdr->ip_src.s_addr; - } - break; - - case RAW_PKT_GET_VXLAN_LOCAL_IP: - { - const struct mesa_ip4_hdr *pip4_hdr; - const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr; - if(NULL == carry_vxlan_ip_layer){ - return -1; - } - - pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr); - int *out_value = (int *)void_value; - *out_value = pip4_hdr->ip_dst.s_addr; - } - break; - - case RAW_PKT_GET_VXLAN_ID: - { - int *out_value = (int *)void_value; - *out_value = htonl((int)p_vxlan_hdr->link_id); - } - break; - - case RAW_PKT_GET_VXLAN_VPNID: - { - int local_tmp_vpn_id; - local_tmp_vpn_id = ((int)p_vxlan_hdr->vlan_id_half_high << 4) | (int)p_vxlan_hdr->vlan_id_half_low; - int *out_value = (int *)void_value; - *out_value = htonl(local_tmp_vpn_id); - } - break; - - case RAW_PKT_GET_VXLAN_SPORT: - { - const struct mesa_ip4_hdr *pip4_hdr; - const struct mesa_udp_hdr *pudp_hdr; - const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr; - if(NULL == carry_vxlan_ip_layer){ - return -1; - } - - pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr); - pudp_hdr = (struct mesa_udp_hdr *)((char *)pip4_hdr + pip4_hdr->ip_hl*4); - unsigned short *out_value = (unsigned short *)void_value; - *out_value = pudp_hdr->uh_sport; /* ���հ��ĽǶ�����, src port��inline�豸��sport */ - } - break; - - case RAW_PKT_GET_VXLAN_ENCAP_TYPE: - { - char *out_value = (char *)void_value; - *out_value = p_vxlan_hdr->link_layer_type; - } - break; - - case RAW_PKT_GET_VXLAN_LINK_DIR: - { - char *out_value = (char *)void_value; - *out_value = p_vxlan_hdr->dir; - } - break; - - /* ���հ��ĽǶ�����, src host��inline�豸��mac */ - case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC: - { - const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, p_eth_hdr->ether_shost, ETH_ALEN); - } - break; - - /* ���հ��ĽǶ�����, dst host�DZ�����mac */ - case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC: - { - const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data; - memcpy(void_value, p_eth_hdr->ether_dhost, ETH_ALEN); - } - break; - } - - return ret; -} - -const void *get_rawpkt_from_streaminfo(const struct streaminfo *pstream) -{ - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - if(pstream_pr->packet_io_context != 0) - { - return pstream_pr->raw_pkt; - } - return NULL; -} - -int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value) -{ - int ret = -1; - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - - if(NULL == out_value){ - return -1; - } - - if((RAW_PKT_GET_DATA == type) - && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){ - const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream); - if(NULL == list_tmp){ - ret = -1; - }else{ - const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value; - *out_list = list_tmp; - ret = 1; - } - return ret; - } - - /* sappv4.2֮��, û��mrtunnat, ����ctrlzone��ȡ��Щvxlan��ص�ֵ, Ҫ��streaminfo->pfatherƫ�ƻ�ȡ */ - switch(type){ - case RAW_PKT_GET_GDEV_IP: - case RAW_PKT_GET_VXLAN_ID: - case RAW_PKT_GET_VXLAN_SPORT: - case RAW_PKT_GET_VXLAN_ENCAP_TYPE: - case RAW_PKT_GET_VXLAN_LINK_DIR: - case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC: - case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC: - case RAW_PKT_GET_VXLAN_VPNID: - case RAW_PKT_GET_VXLAN_LOCAL_IP: - return get_vxlan_info_from_streaminfo(pstream_pr, type, out_value); - break; - } - - return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value); -} - -/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/ -const char *printaddr (const struct layer_addr *paddrinfo,int threadindex) -{ - static char maxbuf[MAX_THREAD_NUM][128]; - char *buf=(char*)maxbuf[threadindex]; - char ip_str[INET6_ADDRSTRLEN]; - struct stream_tuple4_v4 *paddr; - struct stream_tuple4_v6 *paddr6; - - if(NULL == paddrinfo){ - return NULL; - } - - switch(paddrinfo->addrtype){ - case 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); - strncpy (buf, ip_str, 64); - 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)); - } - break; - - case ADDR_TYPE_IPV6: - { - paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr); - memset(buf,0,128); - inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64); - strncpy (buf, ip_str, 64); - 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)); - } - break; - - case __ADDR_TYPE_IP_PAIR_V4: - { - paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr; - memset(buf,0,128); - //strcpy (buf, int_ntoa (paddr->saddr)); - inet_ntop(AF_INET, &paddr->saddr, ip_str, 64); - strncpy (buf, ip_str, 64); - strcat (buf, ">"); - inet_ntop(AF_INET, &paddr->daddr, ip_str, 64); - strcat (buf, ip_str); - } - break; - - case __ADDR_TYPE_IP_PAIR_V6: - { - paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr); - memset(buf,0,128); - inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64); - strncpy (buf, ip_str, 64); - strcat (buf, ">"); - inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64); - strcat (buf, ip_str); - } - break; - - default: - { - return (const char *)"Not support layer type"; - } - break; - } - - return buf; -} - -/* - This is a reentrant version of printaddr(), - Convert tuple4 to string store in out_buf. - Format: 10.0.0.1, 1234->10.0.0.2,5678. -*/ -const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len) -{ - char maxbuf[128]; - char *buf=maxbuf; - char ip_str[INET6_ADDRSTRLEN]; - int addr_str_len; - struct stream_tuple4_v4 *paddr; - struct stream_tuple4_v6 *paddr6; - - if((NULL == paddrinfo) || (NULL == out_buf)){ - return "invalid args"; - } - - if(paddrinfo->addrtype==ADDR_TYPE_IPV4) - { - paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr; - memset(buf,0,128); - //strcpy (buf, int_ntoa (paddr->saddr)); - inet_ntop(AF_INET, &paddr->saddr, ip_str, 64); - strncpy (buf, ip_str, 64); - 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); - strncpy (buf, ip_str,64); - 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"; - } - - addr_str_len = strlen(buf) + 1; /* add EOF */ - if(addr_str_len > out_buf_len){ - return (const char *)"buf len not enough"; - } - - memcpy(out_buf, buf, addr_str_len); - - return out_buf; -} - - -struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info) -{ - void *addr_value; - struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr)); - addr_value = malloc(stack_info->addrlen); - - memcpy(heap_addr, stack_info, sizeof(struct layer_addr)); - memcpy(addr_value, stack_info->paddr, stack_info->addrlen); - heap_addr->paddr = addr_value; - - return heap_addr; -} - -void layer_addr_free(struct layer_addr *paddrinfo) -{ - free(paddrinfo->paddr); - free(paddrinfo); -} - -int get_thread_count(void) -{ - return g_packet_io_thread_num; -} - -/* - ctype: - 'c':count; - 'l':length; -*/ -static inline unsigned long long __get_stream_opt_traffic_raw(int cltype, int iotype, struct streaminfo_private *pstream_pr) -{ - unsigned long long tval; - struct streaminfo *pstream = &pstream_pr->stream_public; - - if('c' == cltype){ /* count */ - if('i' == iotype){ /* inbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverpktnum; - }else{ - tval = pstream->pudpdetail->serverpktnum; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientpktnum; - }else{ - tval = pstream->pudpdetail->clientpktnum; - } - } - }else{ /* outbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientpktnum; - }else{ - tval = pstream->pudpdetail->clientpktnum; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverpktnum; - }else{ - tval = pstream->pudpdetail->serverpktnum; - } - } - } - }else{/* length */ - if('i' == iotype){ /* inbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw; - }else{ - tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw; - }else{ - tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw; - } - } - }else{ /* outbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw; - }else{ - tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw; - }else{ - tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw; - } - } - } - } - - return tval; -} - - - -/* - ctype: - 'c':count; - 'l':length; -*/ -static inline unsigned long long __get_stream_opt_traffic(int cltype, int iotype, struct streaminfo_private *pstream_pr) -{ - unsigned long long tval; - struct streaminfo *pstream = &pstream_pr->stream_public; - - if('c' == cltype){ /* count */ - if('i' == iotype){ /* inbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverpktnum; - }else{ - tval = pstream->pudpdetail->serverpktnum; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientpktnum; - }else{ - tval = pstream->pudpdetail->clientpktnum; - } - } - }else{ /* outbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientpktnum; - }else{ - tval = pstream->pudpdetail->clientpktnum; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverpktnum; - }else{ - tval = pstream->pudpdetail->serverpktnum; - } - } - } - }else{/* length */ - if('i' == iotype){ /* inbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverbytes; - }else{ - tval = pstream->pudpdetail->serverbytes; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientbytes; - }else{ - tval = pstream->pudpdetail->clientbytes; - } - } - }else{ /* outbound */ - if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->clientbytes; - }else{ - tval = pstream->pudpdetail->clientbytes; - } - }else{ - if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){ - tval = pstream->ptcpdetail->serverbytes; - }else{ - tval = pstream->pudpdetail->serverbytes; - } - } - } - } - - return tval; -} - - -int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len) -{ - int ret = -1; - - if((NULL == opt_val) || (opt_val_len <= 0)){ - return -1; - } - - switch((int)opt){ - case (int)MSO_MAX_UNORDER: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - if(opt_val_len != sizeof(struct max_unorder_opt)){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val; - ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val); - } - break; - - case (int)MSO_NEED_ACK: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned char nack = *((unsigned char *)opt_val); - struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - pdetail_pr->needackflag = nack; - ret = 0; - } - break; - - case (int)MSO_TAKEOVER: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() STREAM_TYPE_TCP error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - int takeover = *((int *)opt_val); - struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); - pdetail_pr->takeoverflag = takeover; - ret = 0; - } - break; - - case (int)MSO_TIMEOUT: - { - if(sizeof(short) != opt_val_len){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned short tmout = *((unsigned short *)opt_val); - ret = stream_set_single_stream_timeout(pstream, tmout); - } - break; - - case (int)MSO_IGNORE_RST_FIN: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_IGNORE_RST_FIN error: stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned char igrstfin = *((unsigned char *)opt_val); - struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - pdetail_pr->ignore_rst_fin = igrstfin; - ret = 0; - } - break; - - case MSO_TCPALL_VALID_AFTER_KILL: - { -#if 0 - if(STREAM_TYPE_TCP != pstream->type){ - printf("MESA_set_stream_opt() error: stream type is not tcp!\n"); - ret = -1; - break; - } - unsigned char tcpall_valid = *((unsigned char *)opt_val); - struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - pdetail_pr->tcpall_valid_after_kill = (tcpall_valid == 1 ? 1 : 0); - ret = 0; -#else - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCPALL_VALID_AFTER_KILL error: this option is obsoleted!\n", printaddr(&pstream->addr, pstream->threadnum)); -#endif - } - break; - - case MSO_DROP_STREAM: - { - int drop_flag = *((int *)opt_val); - if(STREAM_TYPE_TCP == pstream->type){ - struct tcpdetail_private *tcp_pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); - tcp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0); - ret = 0; - }else if(STREAM_TYPE_UDP == pstream->type){ - struct udpdetail_private *udp_pdetail_pr=(struct udpdetail_private*)(pstream->pdetail); - udp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0); - ret = 0; - }else{ - sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_set_stream_opt() MSO_DROP_STREAM error: stream type is not tcp or udp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - } - } - break; - - case MSO_TCP_RST_REMEDY: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCP_RST_REMEDY error: stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - int remedy_flag = *((int *)opt_val); - struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); - pdetail_pr->auto_remedy_flag = (remedy_flag != 0 ? 1:0); - ret = 0; - } - break; - - case MSO_DROP_CURRENT_PKT: - { - struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream; - raw_pkt_t *raw_pkt = (raw_pkt_t *)pstream_pr->raw_pkt; - int drop_value = *((int *)opt_val); - if(raw_pkt){ - raw_pkt->drop_current_pkt_flag = drop_value; - }else{ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_DROP_CURRENT_PKT error: current pkt is NULL!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - } - } - break; - case MSO_STREAM_TIMED: - { - if(sizeof(int) != opt_val_len){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned int set_timer_s = *((unsigned short *)opt_val); - struct stream_list *lru_list_root; - struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream; - StreamFunInfo *funinfo = (StreamFunInfo *)pstream_pr->cur_plugin_cb_func; - funinfo->pstream = pstream; - funinfo->set_timer_s = set_timer_s; - if(false == timeout_pending(&funinfo->timeout)) - { - timeout_init(&funinfo->timeout, TIMEOUT_ABS); - G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer_cnt+=1; - } - timeouts_add(G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer, &funinfo->timeout, set_timer_s+g_CurrentTime); - ret = 0; - } - break; - case MSO_STREAM_APPLEND_SEGMENT_ID_LIST: - { - if(sizeof(struct segment_id_list) != opt_val_len){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val; - struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream; - if(pstream_pr->sid_append_list == NULL) - { - if(set_sid_list->sz_sidlist > 0) - { - pstream_pr->sid_append_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list)); - memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short)); - pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist; - } - } - else - { - if(set_sid_list->sz_sidlist > 0) - { - memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short)); - pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist; - } - else - { - memset(pstream_pr->sid_append_list, 0, sizeof(struct segment_id_list)); - } - } - ret = 0; - } - break; - case MSO_STREAM_PREPLEND_SEGMENT_ID_LIST: - { - if(sizeof(struct segment_id_list) != opt_val_len){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val; - struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream; - if(pstream_pr->sid_prepend_list == NULL) - { - if(set_sid_list->sz_sidlist > 0) - { - pstream_pr->sid_prepend_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list)); - memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short)); - pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist; - } - } - else - { - if(set_sid_list->sz_sidlist > 0) - { - memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short)); - pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist; - } - else - { - memset(pstream_pr->sid_prepend_list, 0, sizeof(struct segment_id_list)); - } - } - ret = 0; - } - break; - default: - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() error: unsupport MESA_stream_opt type:%d!\n", printaddr(&pstream->addr, pstream->threadnum), (int)opt); - ret = -1; - break; - } - - return ret; -} - - -static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len) -{ - struct max_unorder_opt out_val; - struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail; - UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0; - - memset(&out_val, 0, sizeof(struct max_unorder_opt)); - if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){ - out_uorder_C2S = pdetail_pr->pserver->maxunorder; - out_val.stream_dir |= DIR_C2S; - } - - if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){ - out_uorder_S2C = pdetail_pr->pclient->maxunorder; - out_val.stream_dir |= DIR_S2C; - } - - out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C; - - memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt)); - - *opt_val_len = sizeof(struct max_unorder_opt); - - return 0; -} - - -static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type) -{ - int i; - char *ptr = (char *)smac_integer_type; - - ptr += 5; /* ָ��long long �ĵ�6���ֽ� */ - - for(i = 0; i < 6; i++){ - *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */ - } -} - -static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo) -{ -#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000) -#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00) -#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0) -#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E) -#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001) - - int i; - const struct streaminfo *mim_stream = pstream->pfather; - const struct layer_addr_mac_in_mac *mim_addr; - const struct layer_addr_mac *mac_addr; - unsigned char *ptr; - unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */ - - while(mim_stream){//���ڶ��mac��ַ�������ֻ�������MAC��ַȡvxlan_info - if((ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype) && - (mim_stream->pfather == NULL)){ - break; - }else{ - mim_stream = mim_stream->pfather; - } - } - - if(NULL == mim_stream){ - return -1; - } - - memset(vxinfo, 0, sizeof(struct vxlan_info)); - - if (ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype) - { - mim_addr = mim_stream->addr.mimac; - sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type); - } - else - { - mac_addr = mim_stream->addr.mac; - sapp_mac_addr_to_long(mac_addr->src_addr.h_source, &smac_integer_type); - } - vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16; - vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10; - vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4; - vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1; - vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR); - - if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype) - { - ptr = vxinfo->inner_smac; - for(i = 0; i < 6; i++, ptr += 3){ - sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]); - } - vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */ - memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6); - - ptr = vxinfo->inner_dmac; - for(i = 0; i < 6; i++, ptr += 3){ - sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]); - } - vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */ - memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6); - } - else - { - ptr = vxinfo->inner_smac; - for(i = 0; i < 6; i++, ptr += 3){ - sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_source[i]); - } - vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */ - memcpy(vxinfo->inner_smac_hex, mac_addr->src_addr.h_source, 6); - - ptr = vxinfo->inner_dmac; - for(i = 0; i < 6; i++, ptr += 3){ - sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_dest[i]); - } - vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */ - memcpy(vxinfo->inner_dmac_hex, mac_addr->src_addr.h_dest, 6); - } - return 0; -} - - -static void *MESA_get_stream_plug_pme_from_platform_entry(const StreamFunInfo *plug_pme_head, const void *this_plug_entry) -{ - void *this_plug_pme = NULL; - - while(plug_pme_head){ - if(plug_pme_head->pfun == this_plug_entry){ - this_plug_pme = plug_pme_head->pAppInfo; - break; - } - plug_pme_head = plug_pme_head->next; - } - - return this_plug_pme; -} - -/* - ���ݲ����ں���������, ��ȡ�����˽�д洢�ռ�ָ��pme. -*/ -static int MESA_get_stream_plug_pme(const struct streaminfo *pstream, void *opt_val, const int *opt_val_len) -{ - int ret = 0; - struct mso_plug_pme *in_arg; - const struct streaminfo_private *stream_pr; - struct tcpdetail_private *ptcp_detail_pr; - struct udpdetail_private *pudp_detail_pr; - - const void *this_plug_entry; - void *plug_pme; - - if((NULL == opt_val) || (NULL == opt_val_len)){ - return -1; - } - - if(*opt_val_len != sizeof(struct mso_plug_pme)){ - return -1; - } - - in_arg = (struct mso_plug_pme *)opt_val; - stream_pr = (struct streaminfo_private *)pstream; - in_arg->plug_pme = NULL; - - this_plug_entry = plugin_get_plug_entry(in_arg->plug_name, in_arg->plug_entry_type); - if(NULL == this_plug_entry){ - sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, can't get plug:%s entry:%s address", - printaddr(&pstream->addr, pstream->threadnum), in_arg->plug_name, in_arg->plug_entry_type); - return -1; - } - - if(STREAM_TYPE_TCP == pstream->type){ - ptcp_detail_pr=(struct tcpdetail_private *)(pstream->pdetail); - plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->apme, this_plug_entry); - if(plug_pme != NULL){ - in_arg->plug_pme = plug_pme; - goto bingo; - } - plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->pAllpktpme, this_plug_entry); - if(plug_pme != NULL){ - in_arg->plug_pme = plug_pme; - goto bingo; - } - }else if(STREAM_TYPE_UDP == pstream->type){ - pudp_detail_pr = (struct udpdetail_private *)(pstream->pdetail); - plug_pme = MESA_get_stream_plug_pme_from_platform_entry(pudp_detail_pr->apme, this_plug_entry); - if(plug_pme != NULL){ - in_arg->plug_pme = plug_pme; - goto bingo; - } - }else{ - sapp_runtime_log(RLOG_LV_FATAL, "%s, MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, not support stream type:%d", printaddr(&pstream->addr, pstream->threadnum),pstream->type); - return -1; - } - - if(NULL == in_arg->plug_pme){ - ret = -1; - } - -bingo: - - return ret; -} - - -static int MESA_get_stream_dup_pkt_stat(const struct streaminfo *pstream, void *opt_val, int *opt_val_len) -{ - const struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream; - int *res_val = (int *)opt_val; - int ret = 0; - - if((0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_all_inject) - && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_tcp) - && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_udp)){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, config DUPLICATE_PKT is not enable", - printaddr(&pstream->addr, pstream->threadnum)); - *res_val = -2; - return 0; - } - - if(pstream_pr->has_duplicate_pkt != 0){ - *res_val = 1; - return 0; - } - - /* �������ظ�������,����û�������ظ��� */ - if(STREAM_TYPE_TCP == pstream->type){ - if(pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */ - *res_val = -2; - sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt", - printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum); - }else{ - *res_val = 0; - } - }else if(STREAM_TYPE_UDP == pstream->type){ - if(pstream->pudpdetail->clientpktnum + pstream->pudpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */ - sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt", - printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum); - *res_val = -2; - }else{ - *res_val = 0; - } - }else{ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, not support stream type:%d", - printaddr(&pstream->addr, pstream->threadnum), pstream->type); - *res_val = -2; - ret = -1; - } - - return ret; -} - -int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len) -{ - int ret = 0; - - if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){ - return -1; - } - - switch((int)opt){ - case (int)MSO_MAX_UNORDER: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){ - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - *opt_val_len = sizeof(struct max_unorder_opt); - ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len); - } - break; - - case (int)MSO_NEED_ACK: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned char *nack = (unsigned char *)opt_val; - struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - *nack = pdetail_pr->needackflag; - *opt_val_len = sizeof(char); - } - break; - - case (int)MSO_TAKEOVER: - { - if(*opt_val_len < (int)sizeof(int)){ - ret = -1; - break; - } - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TAKEOVER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - int *takeover = (int *)opt_val; - struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); - *takeover = pdetail_pr->takeoverflag; - *opt_val_len = sizeof(int); - } - break; - - case (int)MSO_TIMEOUT: - { - if(sizeof(short) != *opt_val_len){ - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned short *tmout = (unsigned short *)opt_val; - struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream; - *tmout = pstream_pr->timeout; - *opt_val_len = sizeof(short); - } - break; - - case (int)MSO_IGNORE_RST_FIN: - { - if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_IGNORE_RST_FIN error:stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned char *igrstfin = (unsigned char *)opt_val; - struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - *igrstfin = pdetail_pr->ignore_rst_fin; - } - break; - - case MSO_TCP_CREATE_LINK_MODE: - { - struct tcpdetail_private *pdetail_pr; - UCHAR *out_val = (UCHAR *)opt_val; - if(STREAM_TYPE_TCP != pstream->type){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TCP_CREATE_LINK_MODE error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - break; - } - - pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - *out_val = pdetail_pr->creat_mod; - *opt_val_len = sizeof(char); - } - break; - - case MSO_TCP_ISN_C2S: - { - struct tcpdetail_private *pdetail_pr; - UINT32 *out_val = (UINT32 *)opt_val; - if(STREAM_TYPE_TCP != pstream->type){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - break; - } - - pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: stream create mode is not by SYN!\n", printaddr(&pstream->addr, pstream->threadnum)); - break; - } - if(0 == pdetail_pr->iserverseq){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: can't get SYN seq!\n", printaddr(&pstream->addr, pstream->threadnum)); - break; - } - - *out_val = pdetail_pr->iserverseq - 1; - *opt_val_len = sizeof(int); - } - break; - - case MSO_TCP_ISN_S2C: - { - /* TODO 1: �����������ظ�, ���ϲ� */ - struct tcpdetail_private *pdetail_pr; - UINT32 *out_val = (UINT32 *)opt_val; - if(STREAM_TYPE_TCP != pstream->type){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); - break; - } - pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: stream create mode is not by SYN!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - - if(0 == pdetail_pr->iclientseq){ - ret = -1; - if(pstream->dir != DIR_C2S) - { - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: can't get SYN/ACK seq!\n",printaddr(&pstream->addr, pstream->threadnum)); - } - break; - } - - *out_val = pdetail_pr->iclientseq - 1; - *opt_val_len = sizeof(int); - } - break; - - case MSO_TCP_SYN_OPT: - { - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - struct tcp_option **out_val = (struct tcp_option **)opt_val; - if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){ - *out_val = pstream_pr->syn_opt_array; - *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */ - ret = 0; - }else{ - ret = -1; - } - } - break; - - case MSO_TCP_SYNACK_OPT: - { - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - struct tcp_option **out_val = (struct tcp_option **)opt_val; - if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){ - *out_val = pstream_pr->synack_opt_array; - *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */ - ret = 0; - }else{ - ret = -1; - } - } - break; - - case MSO_STREAM_TUNNEL_TYPE: - { - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - unsigned short *out_val = (unsigned short *)opt_val; - *out_val = pstream_pr->stream_low_layer_tunnel_type; - ret = 0; - } - break; - - case MSO_STREAM_UP_LAYER_TUNNEL_TYPE: - { - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - unsigned short *out_val = (unsigned short *)opt_val; - *out_val = pstream_pr->stream_carry_up_layer_tunnel_type; - ret = 0; - } - break; - - case MSO_STREAM_CLOSE_REASON: - { - UCHAR *close_reason = (UCHAR *)opt_val; - - if(pstream->opstate != OP_STATE_CLOSE){ - ret = -1; - sapp_runtime_log(RLOG_LV_DEBUG, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:has not closed!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - if(STREAM_TYPE_TCP == pstream->type){ - const struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); - *close_reason = pdetail_pr->link_state; - }else if(STREAM_TYPE_UDP == pstream->type){ - const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; - *close_reason = pstream_pr->stream_close_reason; - }else{ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:unsupport stream type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), pstream->type); - } - } - break; - - case MSO_STREAM_VXLAN_INFO: - if(DEPOLYMENT_MODE_MIRROR != g_topology_mode_raw){ - sapp_runtime_log(RLOG_LV_INFO, "MESA_get_stream_opt() error: can't support option MSO_STREAM_VXLAN_INFO in no mirror mode!"); - return -1; - } - if(*opt_val_len != sizeof(struct vxlan_info)){ - return -1; - } - ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val); - break; - - case MSO_GLOBAL_STREAM_ID: - { - const struct streaminfo_private *pstream_pr; - if(*opt_val_len != sizeof(long long)){ - return -1; - } - pstream_pr = (const struct streaminfo_private *)pstream; - unsigned long long *out_args = (unsigned long long *)opt_val; - unsigned long long dev_id = *out_args; - if(dev_id > 4095){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_GLOBAL_STREAM_ID error:invalid dev_id:%llu!\n", printaddr(&pstream->addr, pstream->threadnum), dev_id); - return -1; - } - unsigned long long local_global_id = pstream_pr->global_stream_id; - - *out_args = local_global_id | (dev_id << 51); - ret = 0; - } - break; - - case MSO_TOTAL_INBOUND_PKT: - { - if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *inbound_pkt = (unsigned long long *)opt_val; - *inbound_pkt = __get_stream_opt_traffic('c', 'i', (struct streaminfo_private *)pstream); - } - break; - - case MSO_TOTAL_OUTBOUND_PKT: - { - if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *outbound_pkt = (unsigned long long *)opt_val; - *outbound_pkt = __get_stream_opt_traffic('c', 'o', (struct streaminfo_private *)pstream); - } - break; - - case MSO_TOTAL_INBOUND_BYTE: - { - if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *inbound_byte = (unsigned long long *)opt_val; - *inbound_byte = __get_stream_opt_traffic('l', 'i', (struct streaminfo_private *)pstream); - } - break; - - case MSO_TOTAL_INBOUND_BYTE_RAW: - { - if(STREAM_TYPE_TCP == pstream->type){ - if(G_TCP_FLOW_STAT_PROJECT_ID == -1){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - }else if(STREAM_TYPE_UDP == pstream->type){ - if(G_UDP_FLOW_STAT_PROJECT_ID == -1){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - }else{ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - - unsigned long long *inbound_byte = (unsigned long long *)opt_val; - *inbound_byte = __get_stream_opt_traffic_raw('l', 'i', (struct streaminfo_private *)pstream); - } - break; - - - case MSO_TOTAL_OUTBOUND_BYTE: - { - if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *outbound_byte = (unsigned long long *)opt_val; - *outbound_byte = __get_stream_opt_traffic('l', 'o', (struct streaminfo_private *)pstream); - } - break; - - case MSO_TOTAL_OUTBOUND_BYTE_RAW: - { - if(STREAM_TYPE_TCP == pstream->type){ - if(G_TCP_FLOW_STAT_PROJECT_ID == -1){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - }else if(STREAM_TYPE_UDP == pstream->type){ - if(G_UDP_FLOW_STAT_PROJECT_ID == -1){ - ret = -1; - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum)); - break; - } - }else{ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - - unsigned long long *outbound_byte = (unsigned long long *)opt_val; - *outbound_byte = __get_stream_opt_traffic_raw('l', 'o', (struct streaminfo_private *)pstream); - } - break; - - case MSO_STREAM_CREATE_TIMESTAMP_MS: - { - if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)) - { - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CREATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *timestamp_ms = (unsigned long long *)opt_val; - *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_create_timestamp_ms; - } - break; - case MSO_STREAM_LASTUPDATE_TIMESTAMP_MS: - { - if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)) - { - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_LASTUPDATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum)); - ret = -1; - break; - } - unsigned long long *timestamp_ms = (unsigned long long *)opt_val; - *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_lastupdate_timestamp_ms; - } - break; - - case MSO_STREAM_PLUG_PME: - ret = MESA_get_stream_plug_pme(pstream, opt_val, opt_val_len); - break; - - case MSO_HAVE_DUP_PKT: - ret = MESA_get_stream_dup_pkt_stat(pstream, opt_val, opt_val_len); - break; - - default: - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), (int)opt); - ret = -1; - break; - } - - return ret; -} - -int is_proxy_stream(const struct streaminfo *pstream) -{ - int ret = 0; - - switch(pstream->type){ - case STREAM_TYPE_SOCKS4: - case STREAM_TYPE_SOCKS5: - case STREAM_TYPE_HTTP_PROXY: - case STREAM_TYPE_OPENVPN: - ret = 1; - break; - - default: - ret = 0; - break; - } - - return ret; -} - - -void set_current_thread_cpu_affinity(int thread_index) -{ - if(sapp_global_val->config.cpu.bind_mask_array_num != 0){ - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(sapp_global_val->config.cpu.bind_mask_array[thread_index], &cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - } - - return; -} - -int get_current_thread_cpu_affinity_id(void) -{ - int i; - cpu_set_t current_cpu_mask; - - CPU_ZERO(¤t_cpu_mask); - - if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), ¤t_cpu_mask) < 0){ - return -1; - } - - int tot_cpu_core = get_nprocs(); - int tot_cpu_set_count = CPU_COUNT(¤t_cpu_mask); - if((tot_cpu_set_count == tot_cpu_core) || (tot_cpu_set_count > 1)){ - /* ȫ����������, ��ʵ����û�а�, - �����������isolcpus, ���㲻���, CPU_COUNT���ܺ������������, - ��������1���϶���û�о�ȷ��ij������ */ - return -1; - } - - for(i = 0; i <= tot_cpu_core; i++){ - if(CPU_ISSET(i, ¤t_cpu_mask)){ - break; - } - } - - return i; -} - - - -extern int project_req_terminal_tag_id; -/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */ -const unsigned char *get_terminal_tag(struct streaminfo *stream) -{ - unsigned char *terminal_tag; - - if(project_req_terminal_tag_id < 0){ - return NULL; - } - - terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id); - - return (const unsigned char *)terminal_tag; -} - -int number_is_2powerN(uint n) -{ - if(n & (n-1)){ - return 0; - } - - return 1; -} - - - -void *dictator_malloc(int thread_seq,size_t size) -{ - /* - if(malloccount%100000==0) - { - printf("malloc=%d,free=%d\n",malloccount,freecount); - } - */ - - if(G_DICTATOR_SW){ -#if USE_MEMPOOL - return __dictator_malloc(thread_seq, size); -#endif - } - - return malloc(size); -} -void dictator_free(int thread_seq,void *pbuf) -{ -#if USE_MEMPOOL - if(G_DICTATOR_SW){ - __dictator_free(thread_seq, pbuf); - } - else -#endif - { -#if SAPP_INSECTICIDE - *((char *)pbuf) = 0xFE; -#endif - free(pbuf); - } -} - -void *dictator_realloc(int thread_seq, void *ptr, size_t size) -{ -#if USE_MEMPOOL - if(G_DICTATOR_SW){ - return __dictator_realloc(thread_seq, ptr, size); - } -#endif - - return realloc(ptr, size); -} - -/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */ -char biz_retval_to_platform(char biz_ret) -{ - char plat_ret = 0; - - if(biz_ret & PROT_STATE_GIVEME){ - plat_ret |= APP_STATE_GIVEME; - } - - if(biz_ret & PROT_STATE_DROPME){ - plat_ret |= APP_STATE_DROPME; - } - - if(biz_ret & PROT_STATE_DROPPKT){ - plat_ret |= APP_STATE_DROPPKT; - } - - return plat_ret; -} - -/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */ -char plat_state_to_biz(char plat_state) -{ - char biz_ret = SESSION_STATE_CLOSE; - - switch(plat_state){ - case OP_STATE_PENDING: - biz_ret = SESSION_STATE_PENDING; - break; - - case OP_STATE_DATA: - biz_ret = SESSION_STATE_DATA; - break; - - case OP_STATE_CLOSE: - biz_ret = SESSION_STATE_CLOSE; - break; - - default: - break; - } - - return biz_ret; -} - - -long long sapp_get_cpu_cycle(void) -{ -#ifdef __x86_64 -#define X86_64_ENV 1 -#endif -#ifdef __x86_64__ -#define X86_64_ENV 1 -#endif - -#ifdef X86_64_ENV - long long l; - long long h; - - __asm__ volatile("rdtsc" : "=a"(l), "=d"(h)); - return (long long )l | ((long long )h<<32); -#else - return 0; -#endif -} - -void sapp_set_current_state(enum sapp_state_t state) -{ - sapp_global_val->individual_volatile->current_state = (int)state; -} - -enum sapp_state_t sapp_get_current_state(void) -{ - return (enum sapp_state_t)sapp_global_val->individual_volatile->current_state; -} - -int sapp_size_of_sapp_global(void) -{ - return sizeof(sapp_global_t); -} - - -int sapp_size_of_streaminfo_private(void) -{ - return sizeof(struct streaminfo_private); -} - -int sapp_size_of_tcpdetail_private(void) -{ - return sizeof(struct tcpdetail_private); -} - -int sapp_size_of_udpdetail_private(void) -{ - return sizeof(struct udpdetail_private); -} - -int sapp_size_of_raw_pkt_t(void) -{ - return sizeof(raw_pkt_t); -} - - -char *sapp_strdup(const char *raw_s) -{ - int buflen = strlen(raw_s) + 1; //add EOF - char *new_s = (char *)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, buflen); - memcpy(new_s, raw_s, buflen); - - return new_s; -} - -int sapp_is_absolute_path(const char *filename) -{ - if('/' == filename[0]){ - return 1; - } - - return 0; -} - -long long sapp_random(void) -{ - struct timespec curtime; - - clock_gettime(CLOCK_MONOTONIC, &curtime); - - return (curtime.tv_nsec * 131) ^ curtime.tv_sec; -} - -int sapp_usleep(int usec) -{ - struct timespec sleep_time_val; - - sleep_time_val.tv_sec = 0; - sleep_time_val.tv_nsec = usec * 1000; - - nanosleep(&sleep_time_val, NULL); - - return 0; -} - - - -#ifdef __cplusplus -} -#endif - +/*
+ ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
+ ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
+*/
+#include "sapp_api.h"
+#include "sapp_private_api.h"
+#include "sapp_declaration.h"
+#include "stream_inc/stream_base.h"
+#include "stream_inc/stream_rawpkt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int G_TCP_FLOW_STAT_PROJECT_ID ;
+extern int G_UDP_FLOW_STAT_PROJECT_ID ;
+
+
+extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
+#if IOMODE_MARSIO
+extern void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id);
+#endif
+
+
+struct detain_pkt* MESA_rawpkt_detain(const struct streaminfo *pstream, const void *rawpkt)
+{
+ if(pstream == NULL || rawpkt == NULL)return NULL;
+
+ raw_pkt_t *p_rawpkt = (raw_pkt_t *)rawpkt;
+ assert(p_rawpkt->magic_num == RAW_PKT_MAGIC_NUM);
+ if(p_rawpkt->magic_num != RAW_PKT_MAGIC_NUM )return NULL;
+
+ if(p_rawpkt->d_pkt)return NULL; // rawpkt can be retained only once
+ if(p_rawpkt->drop_current_pkt_flag == 1)return NULL; // rawpkt need to be drop, can not be retained
+
+ if(sapp_global_val->config.packet_io.depolyment_mode_bin != DEPOLYMENT_MODE_INLINE)return NULL;
+
+ struct detain_pkt *d_pkt = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(struct detain_pkt));
+ d_pkt->original = rawpkt;
+ memcpy(&d_pkt->replica, p_rawpkt, sizeof(raw_pkt_t));
+ d_pkt->replica.append_list=NULL;
+ d_pkt->replica.prepend_list=NULL;
+ if(p_rawpkt->append_list!= NULL && p_rawpkt->append_list->sz_sidlist > 0)
+ {
+ d_pkt->replica.append_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
+ memcpy(d_pkt->replica.append_list->sid_list, p_rawpkt->append_list->sid_list, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
+ d_pkt->replica.append_list->sz_sidlist = p_rawpkt->append_list->sz_sidlist;
+ }
+ if(p_rawpkt->prepend_list!= NULL && p_rawpkt->prepend_list->sz_sidlist > 0)
+ {
+ d_pkt->replica.prepend_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
+ memcpy(d_pkt->replica.prepend_list->sid_list, p_rawpkt->prepend_list->sid_list, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
+ d_pkt->replica.prepend_list->sz_sidlist = p_rawpkt->prepend_list->sz_sidlist;
+ }
+ p_rawpkt->d_pkt = d_pkt;
+ d_pkt->tid = pstream->threadnum;
+
+ return d_pkt;
+}
+
+static void detain_pkt_mem_free(struct detain_pkt *pkt)
+{
+ if(pkt == NULL)return;
+ if(pkt->replica.append_list)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.append_list);
+ }
+ if(pkt->replica.prepend_list)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.prepend_list);
+ }
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt);
+}
+
+int MESA_detain_pkt_forward(struct detain_pkt *pkt)
+{
+ if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
+ {
+ if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
+ {
+ dl_io_fun_list.dl_io_forward_rawpkt(&pkt->replica, pkt->tid);
+ }
+ detain_pkt_mem_free(pkt);
+ pkt = NULL;
+ }
+ else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
+ {
+ if(pkt->mark != RETAIN_RAWPKT)
+ {
+ return -1; // redundant operation, return abnormal
+ }
+ pkt->mark = FORWARD_RAWPKT;
+ }
+ return 0;
+}
+
+void MESA_detain_pkt_free(struct detain_pkt *pkt)
+{
+ if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
+ {
+ if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
+ {
+ dl_io_fun_list.dl_io_free_rawpkt(&pkt->replica, pkt->tid);
+ }
+ detain_pkt_mem_free(pkt);
+ pkt = NULL;
+
+ }
+ else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
+ {
+ if(pkt->mark == RETAIN_RAWPKT)
+ {
+ pkt->mark = FREE_RAWPKT;
+ }
+ }
+}
+
+int MESA_retain_pkt_update(const raw_pkt_t *p_raw_pkt, int pkt_ret)
+{
+ int update_ret = pkt_ret;
+
+ assert(p_raw_pkt->magic_num == RAW_PKT_MAGIC_NUM);
+ if(p_raw_pkt->magic_num != RAW_PKT_MAGIC_NUM )return pkt_ret;
+
+ if (p_raw_pkt->d_pkt != NULL)// have retain operation
+ {
+ if (p_raw_pkt->d_pkt->mark == RETAIN_RAWPKT) //retain pkt in use
+ {
+ if (pkt_ret == PASS)
+ {
+ update_ret = RETAIN;
+ }
+ if (pkt_ret == DROP)
+ {
+ p_raw_pkt->d_pkt->replica.io_lib_pkt_reference = NULL;
+ p_raw_pkt->d_pkt->replica.__lib_raw_pkt_data = NULL;
+ p_raw_pkt->d_pkt->replica.__lib_raw_pkt_len = 0;
+ }
+ p_raw_pkt->d_pkt->original = NULL;
+ }
+ else //During the processing of the original package, the retained pkt being called forward or free, so it is directly released
+ {
+ if (p_raw_pkt->d_pkt->mark == FREE_RAWPKT)
+ {
+ update_ret = DROP;
+ }
+ detain_pkt_mem_free(p_raw_pkt->d_pkt);
+ }
+ }
+ return update_ret;
+}
+
+int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
+{
+ int ret = 0;
+ const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
+
+ if(NULL == voidpkt || NULL == void_value){
+ return -1;
+ }
+
+ if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ���� */
+ return -1;
+ }
+
+ switch(type){
+ case RAW_PKT_GET_DATA:
+ {
+ void **out_value = (void **)void_value;
+ *out_value = (char *)rawpkt->raw_pkt_data + rawpkt->overlay_layer_bytes;
+ }
+ break;
+
+ case RAW_PKT_GET_RAW_PKT_TYPE:
+ {
+ enum addr_type_t *out_value = (enum addr_type_t *)void_value;
+ *out_value = rawpkt->low_layer_type;
+ }
+ break;
+
+ case RAW_PKT_GET_TOT_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len - rawpkt->overlay_layer_bytes;
+ }
+ break;
+
+ case RAW_PKT_GET_TIMESTAMP:
+ {
+ struct timeval *out_value =(struct timeval *)void_value;
+ memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_HDR:
+ {
+ void **out_value = (void **)void_value;
+ const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
+ *out_value = (void *)this_layer_hdr;
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
+ }
+ break;
+
+ case RAW_PKT_GET_VIRTUAL_LINK_ID:
+ {
+ /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
+ sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_VIRTUAL_LINK_ID' in sappv4.2 and later!");
+ ret = -1;
+ }
+ break;
+
+ case RAW_PKT_GET_REHASH_INDEX:
+ {
+ /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
+ sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_REHASH_INDEX' in sappv4.2 and later!");
+ ret = -1;
+ }
+ break;
+
+
+ /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
+ case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC:
+ {
+ const struct mesa_ethernet_hdr *lowest_ehdr;
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
+ if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
+ if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
+ const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
+ if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
+ ret = -1;
+ }else{
+ memcpy(void_value, mr_ctrlzone->g_device_mac, ETH_ALEN);
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
+ ret = -1;
+ }
+ }else{
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
+ }
+ }else{ //from v4.2, without mrtunnat
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
+ }
+ }
+ break;
+
+ /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
+ case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC:
+ {
+ const struct mesa_ethernet_hdr *lowest_ehdr;
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
+ if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
+ if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
+ const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
+ if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
+ ret = -1;
+ }else{
+ memcpy(void_value, mr_ctrlzone->l_device_mac, ETH_ALEN);
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
+ ret = -1;
+ }
+ }else{
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
+ }
+ }else{ //from v4.2, without mrtunnat
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
+ }
+ }
+ break;
+
+ default:
+ sapp_runtime_log(RLOG_LV_FATAL, "get_opt_from_rawpkt(): not support option type: %d", type);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+
+static const struct streaminfo_private *offset_to_vxlan_layer(const struct streaminfo_private *pstream_pr)
+{
+ while(pstream_pr && (ADDR_TYPE_VXLAN != pstream_pr->stream_public.addr.addrtype)){
+ pstream_pr = pstream_pr->pfather_pr;
+ }
+
+ return pstream_pr;
+}
+
+
+static int get_vxlan_info_from_streaminfo(const struct streaminfo_private *pstream_pr, int type, void *void_value)
+{
+ int ret = 0;
+ const struct streaminfo_private *vxlan_pstream_pr;
+ const raw_pkt_t *rawpkt;
+ const inline_vxlan_hdr_t *p_vxlan_hdr;
+
+ if(DEPOLYMENT_MODE_INLINE != g_topology_mode_raw){
+ sapp_runtime_log(RLOG_LV_INFO, "get_rawpkt_opt_from_streaminfo() error: can't support option type: %d in no inline mode!", type);
+ return -1;
+ }
+
+ vxlan_pstream_pr = offset_to_vxlan_layer(pstream_pr);
+ if(NULL == vxlan_pstream_pr){
+ sapp_runtime_log(RLOG_LV_FATAL, "get_rawpkt_opt_from_streaminfo() error, stream:%s not found vxlan layer!",
+ printaddr(&pstream_pr->stream_public.addr, pstream_pr->stream_public.threadnum));
+ return -1;
+ }
+
+ rawpkt = pstream_pr->raw_pkt;
+ p_vxlan_hdr = (inline_vxlan_hdr_t *)((char *)rawpkt->raw_pkt_data + vxlan_pstream_pr->offset_to_raw_pkt_hdr);
+
+ switch(type){
+ case RAW_PKT_GET_GDEV_IP:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ int *out_value = (int *)void_value;
+ *out_value = pip4_hdr->ip_src.s_addr;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_LOCAL_IP:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ int *out_value = (int *)void_value;
+ *out_value = pip4_hdr->ip_dst.s_addr;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_ID:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = htonl((int)p_vxlan_hdr->link_id);
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_VPNID:
+ {
+ int local_tmp_vpn_id;
+ local_tmp_vpn_id = ((int)p_vxlan_hdr->vlan_id_half_high << 4) | (int)p_vxlan_hdr->vlan_id_half_low;
+ int *out_value = (int *)void_value;
+ *out_value = htonl(local_tmp_vpn_id);
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_SPORT:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct mesa_udp_hdr *pudp_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ pudp_hdr = (struct mesa_udp_hdr *)((char *)pip4_hdr + pip4_hdr->ip_hl*4);
+ unsigned short *out_value = (unsigned short *)void_value;
+ *out_value = pudp_hdr->uh_sport; /* ���հ��ĽǶ�����, src port��inline�豸��sport */
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
+ {
+ char *out_value = (char *)void_value;
+ *out_value = p_vxlan_hdr->link_layer_type;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_LINK_DIR:
+ {
+ char *out_value = (char *)void_value;
+ *out_value = p_vxlan_hdr->dir;
+ }
+ break;
+
+ /* ���հ��ĽǶ�����, src host��inline�豸��mac */
+ case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
+ {
+ const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, p_eth_hdr->ether_shost, ETH_ALEN);
+ }
+ break;
+
+ /* ���հ��ĽǶ�����, dst host�DZ�����mac */
+ case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
+ {
+ const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, p_eth_hdr->ether_dhost, ETH_ALEN);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+const void *get_rawpkt_from_streaminfo(const struct streaminfo *pstream)
+{
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ if(pstream_pr->packet_io_context != 0)
+ {
+ return pstream_pr->raw_pkt;
+ }
+ return NULL;
+}
+
+int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
+{
+ int ret = -1;
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+
+ if(NULL == out_value){
+ return -1;
+ }
+
+ if((RAW_PKT_GET_DATA == type)
+ && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
+ const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
+ if(NULL == list_tmp){
+ ret = -1;
+ }else{
+ const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
+ *out_list = list_tmp;
+ ret = 1;
+ }
+ return ret;
+ }
+
+ /* sappv4.2֮��, û��mrtunnat, ����ctrlzone��ȡ��Щvxlan��ص�ֵ, Ҫ��streaminfo->pfatherƫ�ƻ�ȡ */
+ switch(type){
+ case RAW_PKT_GET_GDEV_IP:
+ case RAW_PKT_GET_VXLAN_ID:
+ case RAW_PKT_GET_VXLAN_SPORT:
+ case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
+ case RAW_PKT_GET_VXLAN_LINK_DIR:
+ case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
+ case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
+ case RAW_PKT_GET_VXLAN_VPNID:
+ case RAW_PKT_GET_VXLAN_LOCAL_IP:
+ return get_vxlan_info_from_streaminfo(pstream_pr, type, out_value);
+ break;
+ }
+
+ return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
+}
+
+/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
+const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
+{
+ static char maxbuf[MAX_THREAD_NUM][128];
+ char *buf=(char*)maxbuf[threadindex];
+ char ip_str[INET6_ADDRSTRLEN];
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if(NULL == paddrinfo){
+ return NULL;
+ }
+
+ switch(paddrinfo->addrtype){
+ case 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);
+ strncpy (buf, ip_str, 64);
+ 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));
+ }
+ break;
+
+ case ADDR_TYPE_IPV6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ 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));
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V4:
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ strcat (buf, ">");
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ strcat (buf, ">");
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ default:
+ {
+ return (const char *)"Not support layer type";
+ }
+ break;
+ }
+
+ return buf;
+}
+
+/*
+ This is a reentrant version of printaddr(),
+ Convert tuple4 to string store in out_buf.
+ Format: 10.0.0.1, 1234->10.0.0.2,5678.
+*/
+const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
+{
+ char maxbuf[128];
+ char *buf=maxbuf;
+ char ip_str[INET6_ADDRSTRLEN];
+ int addr_str_len;
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if((NULL == paddrinfo) || (NULL == out_buf)){
+ return "invalid args";
+ }
+
+ if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ 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);
+ strncpy (buf, ip_str,64);
+ 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";
+ }
+
+ addr_str_len = strlen(buf) + 1; /* add EOF */
+ if(addr_str_len > out_buf_len){
+ return (const char *)"buf len not enough";
+ }
+
+ memcpy(out_buf, buf, addr_str_len);
+
+ return out_buf;
+}
+
+
+struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
+{
+ void *addr_value;
+ struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
+ addr_value = malloc(stack_info->addrlen);
+
+ memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
+ memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
+ heap_addr->paddr = addr_value;
+
+ return heap_addr;
+}
+
+void layer_addr_free(struct layer_addr *paddrinfo)
+{
+ free(paddrinfo->paddr);
+ free(paddrinfo);
+}
+
+int get_thread_count(void)
+{
+ return g_packet_io_thread_num;
+}
+
+/*
+ ctype:
+ 'c':count;
+ 'l':length;
+*/
+static inline unsigned long long __get_stream_opt_traffic_raw(int cltype, int iotype, struct streaminfo_private *pstream_pr)
+{
+ unsigned long long tval;
+ struct streaminfo *pstream = &pstream_pr->stream_public;
+
+ if('c' == cltype){ /* count */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }
+ }
+ }else{/* length */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
+ }
+ }
+ }
+ }
+
+ return tval;
+}
+
+
+
+/*
+ ctype:
+ 'c':count;
+ 'l':length;
+*/
+static inline unsigned long long __get_stream_opt_traffic(int cltype, int iotype, struct streaminfo_private *pstream_pr)
+{
+ unsigned long long tval;
+ struct streaminfo *pstream = &pstream_pr->stream_public;
+
+ if('c' == cltype){ /* count */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }
+ }
+ }else{/* length */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverbytes;
+ }else{
+ tval = pstream->pudpdetail->serverbytes;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientbytes;
+ }else{
+ tval = pstream->pudpdetail->clientbytes;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientbytes;
+ }else{
+ tval = pstream->pudpdetail->clientbytes;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverbytes;
+ }else{
+ tval = pstream->pudpdetail->serverbytes;
+ }
+ }
+ }
+ }
+
+ return tval;
+}
+
+
+int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
+{
+ int ret = -1;
+
+ if((NULL == opt_val) || (opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ if(opt_val_len != sizeof(struct max_unorder_opt)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
+ ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char nack = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->needackflag = nack;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() STREAM_TYPE_TCP error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int takeover = *((int *)opt_val);
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->takeoverflag = takeover;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned short tmout = *((unsigned short *)opt_val);
+ ret = stream_set_single_stream_timeout(pstream, tmout);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_IGNORE_RST_FIN error: stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char igrstfin = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->ignore_rst_fin = igrstfin;
+ ret = 0;
+ }
+ break;
+
+ case MSO_TCPALL_VALID_AFTER_KILL:
+ {
+#if 0
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char tcpall_valid = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->tcpall_valid_after_kill = (tcpall_valid == 1 ? 1 : 0);
+ ret = 0;
+#else
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCPALL_VALID_AFTER_KILL error: this option is obsoleted!\n", printaddr(&pstream->addr, pstream->threadnum));
+#endif
+ }
+ break;
+
+ case MSO_DROP_STREAM:
+ {
+ int drop_flag = *((int *)opt_val);
+ if(STREAM_TYPE_TCP == pstream->type){
+ struct tcpdetail_private *tcp_pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ tcp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
+ ret = 0;
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ struct udpdetail_private *udp_pdetail_pr=(struct udpdetail_private*)(pstream->pdetail);
+ udp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
+ ret = 0;
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_set_stream_opt() MSO_DROP_STREAM error: stream type is not tcp or udp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_TCP_RST_REMEDY:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCP_RST_REMEDY error: stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int remedy_flag = *((int *)opt_val);
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->auto_remedy_flag = (remedy_flag != 0 ? 1:0);
+ ret = 0;
+ }
+ break;
+
+ case MSO_DROP_CURRENT_PKT:
+ {
+ struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
+ raw_pkt_t *raw_pkt = (raw_pkt_t *)pstream_pr->raw_pkt;
+ int drop_value = *((int *)opt_val);
+ if(raw_pkt){
+ raw_pkt->drop_current_pkt_flag = drop_value;
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_DROP_CURRENT_PKT error: current pkt is NULL!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ }
+ }
+ break;
+ case MSO_STREAM_TIMED:
+ {
+ if(sizeof(int) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned int set_timer_s = *((unsigned short *)opt_val);
+ struct stream_list *lru_list_root;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ StreamFunInfo *funinfo = (StreamFunInfo *)pstream_pr->cur_plugin_cb_func;
+ funinfo->pstream = pstream;
+ funinfo->set_timer_s = set_timer_s;
+ if(false == timeout_pending(&funinfo->timeout))
+ {
+ timeout_init(&funinfo->timeout, TIMEOUT_ABS);
+ G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer_cnt+=1;
+ }
+ timeouts_add(G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer, &funinfo->timeout, set_timer_s+g_CurrentTime);
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_APPLEND_SEGMENT_ID_LIST:
+ {
+ if(sizeof(struct segment_id_list) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->sid_append_list == NULL)
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ pstream_pr->sid_append_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
+ memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ }
+ else
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ else
+ {
+ memset(pstream_pr->sid_append_list, 0, sizeof(struct segment_id_list));
+ }
+ }
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_PREPLEND_SEGMENT_ID_LIST:
+ {
+ if(sizeof(struct segment_id_list) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->sid_prepend_list == NULL)
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ pstream_pr->sid_prepend_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
+ memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ }
+ else
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ else
+ {
+ memset(pstream_pr->sid_prepend_list, 0, sizeof(struct segment_id_list));
+ }
+ }
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_SET_DATAMETA_TRACE_ID:
+ {
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->stream_trace_id>0)
+ {
+ break;
+ }
+ pstream_pr->stream_trace_id=*((unsigned long long *)opt_val);
+ }
+ break;
+ default:
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() error: unsupport MESA_stream_opt type:%d!\n", printaddr(&pstream->addr, pstream->threadnum), (int)opt);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
+{
+ struct max_unorder_opt out_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
+ UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
+
+ memset(&out_val, 0, sizeof(struct max_unorder_opt));
+ if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
+ out_uorder_C2S = pdetail_pr->pserver->maxunorder;
+ out_val.stream_dir |= DIR_C2S;
+ }
+
+ if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
+ out_uorder_S2C = pdetail_pr->pclient->maxunorder;
+ out_val.stream_dir |= DIR_S2C;
+ }
+
+ out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
+
+ memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
+
+ *opt_val_len = sizeof(struct max_unorder_opt);
+
+ return 0;
+}
+
+
+static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type)
+{
+ int i;
+ char *ptr = (char *)smac_integer_type;
+
+ ptr += 5; /* ָ��long long �ĵ�6���ֽ� */
+
+ for(i = 0; i < 6; i++){
+ *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */
+ }
+}
+
+static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo)
+{
+#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000)
+#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00)
+#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0)
+#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E)
+#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001)
+
+ int i;
+ const struct streaminfo *mim_stream = pstream->pfather;
+ const struct layer_addr_mac_in_mac *mim_addr;
+ const struct layer_addr_mac *mac_addr;
+ unsigned char *ptr;
+ unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */
+
+ while(mim_stream){//���ڶ��mac��ַ�������ֻ�������MAC��ַȡvxlan_info
+ if((ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype) &&
+ (mim_stream->pfather == NULL)){
+ break;
+ }else{
+ mim_stream = mim_stream->pfather;
+ }
+ }
+
+ if(NULL == mim_stream){
+ return -1;
+ }
+
+ memset(vxinfo, 0, sizeof(struct vxlan_info));
+
+ if (ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ mim_addr = mim_stream->addr.mimac;
+ sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type);
+ }
+ else
+ {
+ mac_addr = mim_stream->addr.mac;
+ sapp_mac_addr_to_long(mac_addr->src_addr.h_source, &smac_integer_type);
+ }
+ vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16;
+ vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10;
+ vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4;
+ vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1;
+ vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR);
+
+ if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6);
+ }
+ else
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_source[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mac_addr->src_addr.h_source, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_dest[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mac_addr->src_addr.h_dest, 6);
+ }
+ return 0;
+}
+
+
+static void *MESA_get_stream_plug_pme_from_platform_entry(const StreamFunInfo *plug_pme_head, const void *this_plug_entry)
+{
+ void *this_plug_pme = NULL;
+
+ while(plug_pme_head){
+ if(plug_pme_head->pfun == this_plug_entry){
+ this_plug_pme = plug_pme_head->pAppInfo;
+ break;
+ }
+ plug_pme_head = plug_pme_head->next;
+ }
+
+ return this_plug_pme;
+}
+
+/*
+ ���ݲ����ں���������, ��ȡ�����˽�д洢�ռ�ָ��pme.
+*/
+static int MESA_get_stream_plug_pme(const struct streaminfo *pstream, void *opt_val, const int *opt_val_len)
+{
+ int ret = 0;
+ struct mso_plug_pme *in_arg;
+ const struct streaminfo_private *stream_pr;
+ struct tcpdetail_private *ptcp_detail_pr;
+ struct udpdetail_private *pudp_detail_pr;
+
+ const void *this_plug_entry;
+ void *plug_pme;
+
+ if((NULL == opt_val) || (NULL == opt_val_len)){
+ return -1;
+ }
+
+ if(*opt_val_len != sizeof(struct mso_plug_pme)){
+ return -1;
+ }
+
+ in_arg = (struct mso_plug_pme *)opt_val;
+ stream_pr = (struct streaminfo_private *)pstream;
+ in_arg->plug_pme = NULL;
+
+ this_plug_entry = plugin_get_plug_entry(in_arg->plug_name, in_arg->plug_entry_type);
+ if(NULL == this_plug_entry){
+ sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, can't get plug:%s entry:%s address",
+ printaddr(&pstream->addr, pstream->threadnum), in_arg->plug_name, in_arg->plug_entry_type);
+ return -1;
+ }
+
+ if(STREAM_TYPE_TCP == pstream->type){
+ ptcp_detail_pr=(struct tcpdetail_private *)(pstream->pdetail);
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->apme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->pAllpktpme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ pudp_detail_pr = (struct udpdetail_private *)(pstream->pdetail);
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(pudp_detail_pr->apme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "%s, MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, not support stream type:%d", printaddr(&pstream->addr, pstream->threadnum),pstream->type);
+ return -1;
+ }
+
+ if(NULL == in_arg->plug_pme){
+ ret = -1;
+ }
+
+bingo:
+
+ return ret;
+}
+
+
+static int MESA_get_stream_dup_pkt_stat(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
+{
+ const struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
+ int *res_val = (int *)opt_val;
+ int ret = 0;
+
+ if((0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_all_inject)
+ && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_tcp)
+ && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_udp)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, config DUPLICATE_PKT is not enable",
+ printaddr(&pstream->addr, pstream->threadnum));
+ *res_val = -2;
+ return 0;
+ }
+
+ if(pstream_pr->has_duplicate_pkt != 0){
+ *res_val = 1;
+ return 0;
+ }
+
+ /* �������ظ�������,����û�������ظ��� */
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
+ *res_val = -2;
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
+ }else{
+ *res_val = 0;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(pstream->pudpdetail->clientpktnum + pstream->pudpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
+ *res_val = -2;
+ }else{
+ *res_val = 0;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, not support stream type:%d",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->type);
+ *res_val = -2;
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
+{
+ int ret = 0;
+
+ if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ *opt_val_len = sizeof(struct max_unorder_opt);
+ ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char *nack = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *nack = pdetail_pr->needackflag;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(*opt_val_len < (int)sizeof(int)){
+ ret = -1;
+ break;
+ }
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TAKEOVER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int *takeover = (int *)opt_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ *takeover = pdetail_pr->takeoverflag;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != *opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned short *tmout = (unsigned short *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ *tmout = pstream_pr->timeout;
+ *opt_val_len = sizeof(short);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_IGNORE_RST_FIN error:stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char *igrstfin = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *igrstfin = pdetail_pr->ignore_rst_fin;
+ }
+ break;
+
+ case MSO_TCP_CREATE_LINK_MODE:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UCHAR *out_val = (UCHAR *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TCP_CREATE_LINK_MODE error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *out_val = pdetail_pr->creat_mod;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case MSO_TCP_ISN_C2S:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: stream create mode is not by SYN!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ if(0 == pdetail_pr->iserverseq){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: can't get SYN seq!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ *out_val = pdetail_pr->iserverseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_ISN_S2C:
+ {
+ /* TODO 1: �����������ظ�, ���ϲ� */
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: stream create mode is not by SYN!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ if(0 == pdetail_pr->iclientseq){
+ ret = -1;
+ if(pstream->dir != DIR_C2S)
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: can't get SYN/ACK seq!\n",printaddr(&pstream->addr, pstream->threadnum));
+ }
+ break;
+ }
+
+ *out_val = pdetail_pr->iclientseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_SYN_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
+ *out_val = pstream_pr->syn_opt_array;
+ *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_TCP_SYNACK_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
+ *out_val = pstream_pr->synack_opt_array;
+ *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_STREAM_TUNNEL_TYPE:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned short *out_val = (unsigned short *)opt_val;
+ *out_val = pstream_pr->stream_low_layer_tunnel_type;
+ ret = 0;
+ }
+ break;
+
+ case MSO_STREAM_UP_LAYER_TUNNEL_TYPE:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned short *out_val = (unsigned short *)opt_val;
+ *out_val = pstream_pr->stream_carry_up_layer_tunnel_type;
+ ret = 0;
+ }
+ break;
+
+ case MSO_STREAM_CLOSE_REASON:
+ {
+ UCHAR *close_reason = (UCHAR *)opt_val;
+
+ if(pstream->opstate != OP_STATE_CLOSE){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:has not closed!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ if(STREAM_TYPE_TCP == pstream->type){
+ const struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *close_reason = pdetail_pr->link_state;
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ *close_reason = pstream_pr->stream_close_reason;
+ }else{
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:unsupport stream type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), pstream->type);
+ }
+ }
+ break;
+
+ case MSO_STREAM_VXLAN_INFO:
+ if(DEPOLYMENT_MODE_MIRROR != g_topology_mode_raw){
+ sapp_runtime_log(RLOG_LV_INFO, "MESA_get_stream_opt() error: can't support option MSO_STREAM_VXLAN_INFO in no mirror mode!");
+ return -1;
+ }
+ if(*opt_val_len != sizeof(struct vxlan_info)){
+ return -1;
+ }
+ ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val);
+ break;
+
+ case MSO_GLOBAL_STREAM_ID:
+ {
+ const struct streaminfo_private *pstream_pr;
+ if(*opt_val_len != sizeof(long long)){
+ return -1;
+ }
+ pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned long long *out_args = (unsigned long long *)opt_val;
+ unsigned long long dev_id = *out_args;
+ if(dev_id > 4095){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_GLOBAL_STREAM_ID error:invalid dev_id:%llu!\n", printaddr(&pstream->addr, pstream->threadnum), dev_id);
+ return -1;
+ }
+ unsigned long long local_global_id = pstream_pr->global_stream_id;
+
+ *out_args = local_global_id | (dev_id << 51);
+ ret = 0;
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_PKT:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *inbound_pkt = (unsigned long long *)opt_val;
+ *inbound_pkt = __get_stream_opt_traffic('c', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_OUTBOUND_PKT:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *outbound_pkt = (unsigned long long *)opt_val;
+ *outbound_pkt = __get_stream_opt_traffic('c', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_BYTE:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *inbound_byte = (unsigned long long *)opt_val;
+ *inbound_byte = __get_stream_opt_traffic('l', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_BYTE_RAW:
+ {
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+
+ unsigned long long *inbound_byte = (unsigned long long *)opt_val;
+ *inbound_byte = __get_stream_opt_traffic_raw('l', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+
+ case MSO_TOTAL_OUTBOUND_BYTE:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *outbound_byte = (unsigned long long *)opt_val;
+ *outbound_byte = __get_stream_opt_traffic('l', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_OUTBOUND_BYTE_RAW:
+ {
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+
+ unsigned long long *outbound_byte = (unsigned long long *)opt_val;
+ *outbound_byte = __get_stream_opt_traffic_raw('l', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_STREAM_CREATE_TIMESTAMP_MS:
+ {
+ if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CREATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
+ *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_create_timestamp_ms;
+ }
+ break;
+ case MSO_STREAM_LASTUPDATE_TIMESTAMP_MS:
+ {
+ if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_LASTUPDATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
+ *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_lastupdate_timestamp_ms;
+ }
+ break;
+
+ case MSO_STREAM_PLUG_PME:
+ ret = MESA_get_stream_plug_pme(pstream, opt_val, opt_val_len);
+ break;
+
+ case MSO_HAVE_DUP_PKT:
+ ret = MESA_get_stream_dup_pkt_stat(pstream, opt_val, opt_val_len);
+ break;
+
+ default:
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), (int)opt);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int is_proxy_stream(const struct streaminfo *pstream)
+{
+ int ret = 0;
+
+ switch(pstream->type){
+ case STREAM_TYPE_SOCKS4:
+ case STREAM_TYPE_SOCKS5:
+ case STREAM_TYPE_HTTP_PROXY:
+ case STREAM_TYPE_OPENVPN:
+ ret = 1;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+
+void set_current_thread_cpu_affinity(int thread_index)
+{
+ if(sapp_global_val->config.cpu.bind_mask_array_num != 0){
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(sapp_global_val->config.cpu.bind_mask_array[thread_index], &cpuset);
+ pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+ }
+
+ return;
+}
+
+int get_current_thread_cpu_affinity_id(void)
+{
+ int i;
+ cpu_set_t current_cpu_mask;
+
+ CPU_ZERO(¤t_cpu_mask);
+
+ if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), ¤t_cpu_mask) < 0){
+ return -1;
+ }
+
+ int tot_cpu_core = get_nprocs();
+ int tot_cpu_set_count = CPU_COUNT(¤t_cpu_mask);
+ if((tot_cpu_set_count == tot_cpu_core) || (tot_cpu_set_count > 1)){
+ /* ȫ����������, ��ʵ����û�а�,
+ �����������isolcpus, ���㲻���, CPU_COUNT���ܺ������������,
+ ��������1���϶���û�о�ȷ��ij������ */
+ return -1;
+ }
+
+ for(i = 0; i <= tot_cpu_core; i++){
+ if(CPU_ISSET(i, ¤t_cpu_mask)){
+ break;
+ }
+ }
+
+ return i;
+}
+
+
+
+extern int project_req_terminal_tag_id;
+/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
+const unsigned char *get_terminal_tag(struct streaminfo *stream)
+{
+ unsigned char *terminal_tag;
+
+ if(project_req_terminal_tag_id < 0){
+ return NULL;
+ }
+
+ terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
+
+ return (const unsigned char *)terminal_tag;
+}
+
+int number_is_2powerN(uint n)
+{
+ if(n & (n-1)){
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+void *dictator_malloc(int thread_seq,size_t size)
+{
+ /*
+ if(malloccount%100000==0)
+ {
+ printf("malloc=%d,free=%d\n",malloccount,freecount);
+ }
+ */
+
+ if(G_DICTATOR_SW){
+#if USE_MEMPOOL
+ return __dictator_malloc(thread_seq, size);
+#endif
+ }
+
+ return malloc(size);
+}
+void dictator_free(int thread_seq,void *pbuf)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ __dictator_free(thread_seq, pbuf);
+ }
+ else
+#endif
+ {
+#if SAPP_INSECTICIDE
+ *((char *)pbuf) = 0xFE;
+#endif
+ free(pbuf);
+ }
+}
+
+void *dictator_realloc(int thread_seq, void *ptr, size_t size)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ return __dictator_realloc(thread_seq, ptr, size);
+ }
+#endif
+
+ return realloc(ptr, size);
+}
+
+/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
+char biz_retval_to_platform(char biz_ret)
+{
+ char plat_ret = 0;
+
+ if(biz_ret & PROT_STATE_GIVEME){
+ plat_ret |= APP_STATE_GIVEME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPME){
+ plat_ret |= APP_STATE_DROPME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPPKT){
+ plat_ret |= APP_STATE_DROPPKT;
+ }
+
+ return plat_ret;
+}
+
+/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
+char plat_state_to_biz(char plat_state)
+{
+ char biz_ret = SESSION_STATE_CLOSE;
+
+ switch(plat_state){
+ case OP_STATE_PENDING:
+ biz_ret = SESSION_STATE_PENDING;
+ break;
+
+ case OP_STATE_DATA:
+ biz_ret = SESSION_STATE_DATA;
+ break;
+
+ case OP_STATE_CLOSE:
+ biz_ret = SESSION_STATE_CLOSE;
+ break;
+
+ default:
+ break;
+ }
+
+ return biz_ret;
+}
+
+
+long long sapp_get_cpu_cycle(void)
+{
+#ifdef __x86_64
+#define X86_64_ENV 1
+#endif
+#ifdef __x86_64__
+#define X86_64_ENV 1
+#endif
+
+#ifdef X86_64_ENV
+ long long l;
+ long long h;
+
+ __asm__ volatile("rdtsc" : "=a"(l), "=d"(h));
+ return (long long )l | ((long long )h<<32);
+#else
+ return 0;
+#endif
+}
+
+void sapp_set_current_state(enum sapp_state_t state)
+{
+ sapp_global_val->individual_volatile->current_state = (int)state;
+}
+
+enum sapp_state_t sapp_get_current_state(void)
+{
+ return (enum sapp_state_t)sapp_global_val->individual_volatile->current_state;
+}
+
+int sapp_size_of_sapp_global(void)
+{
+ return sizeof(sapp_global_t);
+}
+
+
+int sapp_size_of_streaminfo_private(void)
+{
+ return sizeof(struct streaminfo_private);
+}
+
+int sapp_size_of_tcpdetail_private(void)
+{
+ return sizeof(struct tcpdetail_private);
+}
+
+int sapp_size_of_udpdetail_private(void)
+{
+ return sizeof(struct udpdetail_private);
+}
+
+int sapp_size_of_raw_pkt_t(void)
+{
+ return sizeof(raw_pkt_t);
+}
+
+
+char *sapp_strdup(const char *raw_s)
+{
+ int buflen = strlen(raw_s) + 1; //add EOF
+ char *new_s = (char *)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, buflen);
+ memcpy(new_s, raw_s, buflen);
+
+ return new_s;
+}
+
+int sapp_is_absolute_path(const char *filename)
+{
+ if('/' == filename[0]){
+ return 1;
+ }
+
+ return 0;
+}
+
+long long sapp_random(void)
+{
+ struct timespec curtime;
+
+ clock_gettime(CLOCK_MONOTONIC, &curtime);
+
+ return (curtime.tv_nsec * 131) ^ curtime.tv_sec;
+}
+
+int sapp_usleep(int usec)
+{
+ struct timespec sleep_time_val;
+
+ sleep_time_val.tv_sec = 0;
+ sleep_time_val.tv_nsec = usec * 1000;
+
+ nanosleep(&sleep_time_val, NULL);
+
+ return 0;
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
|
