diff options
| author | liuyang <[email protected]> | 2018-11-30 17:25:48 +0800 |
|---|---|---|
| committer | liuyang <[email protected]> | 2018-11-30 17:25:48 +0800 |
| commit | 489f124af389ff0eae4a4489e09acbf834237fc4 (patch) | |
| tree | ae037d9233580d5c5a76ed7baa5d5f1866add297 | |
| parent | 890f12f7a7607a7d39657373618a80c18f87a147 (diff) | |
20181130更新
| -rw-r--r-- | kni_comm.c | 6 | ||||
| -rw-r--r-- | kni_entry.c | 110 | ||||
| -rw-r--r-- | kni_entry.h | 10 | ||||
| -rw-r--r-- | kni_intercept.c | 1487 | ||||
| -rw-r--r-- | kni_intercept.h | 24 |
5 files changed, 1593 insertions, 44 deletions
@@ -492,9 +492,9 @@ int kni_filestate2_init() char fs2_filename[KNI_MAX_BUFLEN]={0}; char fs2_sip[KNI_MAX_BUFLEN]={0}; - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_filename",fs2_filename,KNI_MAX_BUFLEN,(char*)"./log/kni_fs2.log"); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_sip",fs2_sip,KNI_MAX_BUFLEN,(char*)"0.0.0.0"); - MESA_load_profile_uint_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,0); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_filename",fs2_filename,KNI_MAX_BUFLEN,(char*)"./log/kni_fs2.log"); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_sip",fs2_sip,KNI_MAX_BUFLEN,(char*)"0.0.0.0"); + MESA_load_profile_uint_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,0); g_kni_fs2_info.handler=FS_create_handle(); diff --git a/kni_entry.c b/kni_entry.c index b37f11a..567fda7 100644 --- a/kni_entry.c +++ b/kni_entry.c @@ -10,7 +10,7 @@ -int g_kni_version_VERSION_20181125_addlog; +int g_kni_version_VERSION_20181129; struct kni_var_comm g_kni_comminfo; struct kni_var_struct g_kni_structinfo; @@ -28,6 +28,7 @@ int kni_init_pmeinfo(void** pme) { struct kni_pme_info* pmeinfo=(struct kni_pme_info*)malloc(sizeof(struct kni_pme_info)); memset(pmeinfo,0,sizeof(struct kni_pme_info)); + pmeinfo->tun_index = -1; *pme=pmeinfo; return 0; @@ -541,7 +542,6 @@ char kni_first_tcpdata(const struct streaminfo* pstream,const void* a_packet,str long elapse=0; char ret=APP_STATE_FAWPKT|APP_STATE_DROPME; - int htable_ret = 0; int domain_len=0; char domain[KNI_DEFAULT_MTU]={0}; @@ -693,11 +693,16 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p if(datalen>0)//TODO:get link create mode from sapp { ret=kni_first_tcpdata(pstream,a_packet,pmeinfo,data,datalen); - if((pmeinfo->action == KNI_ACTION_MONITOR) && (pmeinfo->protocol==KNI_FLAG_HTTP) ||(pmeinfo->protocol==KNI_FLAG_SSL)) + if((pmeinfo->action == KNI_ACTION_MONITOR) && ((pmeinfo->protocol==KNI_FLAG_HTTP) ||(pmeinfo->protocol==KNI_FLAG_SSL))) { if(g_kni_switch_info.write_listq_switch == 1) { - ret = kni_add_lqueue(ADDR_TYPE_IPV4,thread_seq,(char*)ipv4_hdr,iplen,pstream); + if(pmeinfo->tun_index<0) + { + pmeinfo->tun_index=random()%g_kni_comminfo.tun_threadnum; + } + + ret = kni_add_lqueue(ADDR_TYPE_IPV4,thread_seq,(char*)ipv4_hdr,iplen,pstream,pmeinfo->tun_index); } else { @@ -789,7 +794,14 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei kni_filestate2_set(pstream->threadnum,COLUME_INTERCEPT,0,1); if(g_kni_switch_info.write_listq_switch == 1) { - ret = kni_add_lqueue(ADDR_TYPE_IPV4,thread_seq,(char*)a_packet,iplen,pstream); + if(pmeinfo->tun_index<0) + { + pmeinfo->tun_index=random()%g_kni_comminfo.tun_threadnum; + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"get tun_index","index:%d",pmeinfo->tun_index); + + } + + ret = kni_add_lqueue(ADDR_TYPE_IPV4,thread_seq,(char*)a_packet,iplen,pstream,pmeinfo->tun_index); } else { @@ -826,8 +838,6 @@ char kni_close_opstate(const struct streaminfo* pstream,struct kni_pme_info* pme char ret=APP_STATE_FAWPKT|APP_STATE_DROPME; int htable_ret = 0; - struct stream_tuple4_v4 ipv4_addr; - struct stream_tuple4_v6 ipv6_addr; if(a_packet==NULL) { @@ -1202,15 +1212,19 @@ int init_profile_info() //kni.conf - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"replay_win_update",&(g_kni_switch_info.replay_win_update),1); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"default_work_mode",&(g_kni_switch_info.maat_default_mode),KNI_DEFAULT_MODE_INTERCEPT); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"ratelimit_switch",&(g_kni_switch_info.ratelimit_switch),1); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"replace_switch",&(g_kni_switch_info.replace_switch),1); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"sendpkt_mode",&(g_kni_switch_info.sendpkt_mode),0); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"write_listqueue_switch",&(g_kni_switch_info.write_listq_switch),0); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"replay_win_update",&(g_kni_switch_info.replay_win_update),1); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"default_work_mode",&(g_kni_switch_info.maat_default_mode),KNI_DEFAULT_MODE_INTERCEPT); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"ratelimit_switch",&(g_kni_switch_info.ratelimit_switch),1); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"replace_switch",&(g_kni_switch_info.replace_switch),1); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"sendpkt_mode",&(g_kni_switch_info.sendpkt_mode),0); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"write_listqueue_switch",&(g_kni_switch_info.write_listq_switch),0); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"send_fds_mode",&(g_kni_switch_info.send_fds_mode),0); + + + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"domain_path",g_kni_comminfo.domain_path,KNI_CONF_MAXLEN,"/home/server_unixsocket_file"); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"socketopt_mark",&(g_kni_comminfo.mark),101); + - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"domain_path",g_kni_comminfo.domain_path,KNI_CONF_MAXLEN,"/home/server_unixsocket_file"); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"socketopt_mark",&(g_kni_comminfo.mark),101); return 0; } @@ -1252,8 +1266,8 @@ int init_kni_runtimelog() char logger_filepath[KNI_CONF_MAXLEN]={0}; - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_level",&logger_level,RLOG_LV_INFO); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_filepath",logger_filepath,KNI_CONF_MAXLEN,"./log/kni.log"); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"logger_level",&logger_level,RLOG_LV_INFO); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_MAIN_MODE,(char*)"logger_filepath",logger_filepath,KNI_CONF_MAXLEN,"./log/kni.log"); g_kni_comminfo.logger=MESA_create_runtime_log_handle(logger_filepath,logger_level); @@ -1289,15 +1303,15 @@ int init_kni_dyn_maat_info() char stat_file_dir[KNI_CONF_MAXLEN]={0}; - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_maat_readconf_mode",&maat_readconf_mode,KNI_READCONF_IRIS); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_scandir_interval",&scandir_interval,KNI_SCANDIR_INTERVAL); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_effect_interval",&effect_interval,KNI_EFFECT_INTERVAL); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_redis_db_index",&redis_db_index,0); - MESA_load_profile_int_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_redis_port",(int*)&redis_port); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_maat_readconf_mode",&maat_readconf_mode,KNI_READCONF_IRIS); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_scandir_interval",&scandir_interval,KNI_SCANDIR_INTERVAL); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_effect_interval",&effect_interval,KNI_EFFECT_INTERVAL); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_redis_db_index",&redis_db_index,0); + MESA_load_profile_int_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_redis_port",(int*)&redis_port); - MESA_load_profile_string_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_redis_server",redis_ip,INET_ADDRSTRLEN); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_stat_file_path",stat_file_dir,KNI_CONF_MAXLEN,KNI_DYN_STAT_FILEPATH); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"dyn_table_info_path",table_info_path,KNI_CONF_MAXLEN,KNI_TABLEINFO_PATH); + MESA_load_profile_string_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_redis_server",redis_ip,INET_ADDRSTRLEN); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_stat_file_path",stat_file_dir,KNI_CONF_MAXLEN,KNI_DYN_STAT_FILEPATH); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_DYNMAAT_MODE,(char*)"dyn_table_info_path",table_info_path,KNI_CONF_MAXLEN,KNI_TABLEINFO_PATH); g_kni_maatinfo.ipd_dyn_maat_feather=Maat_feather(g_iThreadNum,table_info_path,g_kni_comminfo.logger); @@ -1363,17 +1377,17 @@ int init_kni_static_maat_info() char inc_cfg_dir[KNI_CONF_MAXLEN]={0}; - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"maat_readconf_mode",&maat_readconf_mode,KNI_READCONF_IRIS); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"scandir_interval",&scandir_interval,KNI_SCANDIR_INTERVAL); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"effect_interval",&effect_interval,KNI_EFFECT_INTERVAL); - MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_db_index",&redis_db_index,0); - MESA_load_profile_int_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_port",(int*)&redis_port); - - MESA_load_profile_string_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_server",redis_ip,INET_ADDRSTRLEN); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"table_info_path",table_info_path,KNI_CONF_MAXLEN,KNI_TABLEINFO_PATH); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"inc_cfg_dir",inc_cfg_dir,KNI_CONF_MAXLEN,KNI_INCCFG_FILEPATH); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"stat_file_path",stat_file_dir,KNI_CONF_MAXLEN,KNI_STAT_FILEPATH); - MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"full_cfg_dir",full_cfg_dir,KNI_CONF_MAXLEN,KNI_FULLCFG_FILEPATH); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"maat_readconf_mode",&maat_readconf_mode,KNI_READCONF_IRIS); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"scandir_interval",&scandir_interval,KNI_SCANDIR_INTERVAL); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"effect_interval",&effect_interval,KNI_EFFECT_INTERVAL); + MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"redis_db_index",&redis_db_index,0); + MESA_load_profile_int_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"redis_port",(int*)&redis_port); + + MESA_load_profile_string_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"redis_server",redis_ip,INET_ADDRSTRLEN); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"table_info_path",table_info_path,KNI_CONF_MAXLEN,KNI_TABLEINFO_PATH); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"inc_cfg_dir",inc_cfg_dir,KNI_CONF_MAXLEN,KNI_INCCFG_FILEPATH); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"stat_file_path",stat_file_dir,KNI_CONF_MAXLEN,KNI_STAT_FILEPATH); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_STICMAAT_MODE,(char*)"full_cfg_dir",full_cfg_dir,KNI_CONF_MAXLEN,KNI_FULLCFG_FILEPATH); g_kni_maatinfo.maat_feather=Maat_feather(g_iThreadNum,table_info_path,g_kni_comminfo.logger); @@ -1445,12 +1459,24 @@ int init_kni_project() } +int init_kni_tunprocess() +{ + int i=0; + pthread_t pid_read_tun; + + for(i=0;i<g_kni_comminfo.tun_threadnum;i++) + { + g_kni_threadseq[i]=i; + pthread_create(&pid_read_tun,NULL,pthread_process_tun,&(g_kni_threadseq[i])); + } + + return 0; +} int init_kni_sendpkt() { int i=0; - pthread_t pid_read_tun; kni_read_cardname(); @@ -1465,9 +1491,6 @@ int init_kni_sendpkt() return -1; } - g_kni_threadseq[i]=i; - pthread_create(&pid_read_tun,NULL,pthread_process_tun,&(g_kni_threadseq[i])); - } return 0; @@ -1485,7 +1508,7 @@ int init_kni_lqueue() return -1; } - for(i=0;i<g_iThreadNum;i++) + for(i=0;i<g_kni_comminfo.tun_threadnum;i++) { g_kni_structinfo.lqueue_write_tun[i] = MESA_lqueue_create(KNI_THREAD_SAFE,KNI_LQUEUE_MAXNUM); if(g_kni_structinfo.lqueue_write_tun[i] == NULL) @@ -1504,6 +1527,9 @@ extern "C" char kni_init() pthread_t pid_kni_filestat2; + g_kni_comminfo.tun_threadnum = g_iThreadNum; +// g_kni_comminfo.tun_threadnum = 5; + init_profile_info(); @@ -1555,6 +1581,8 @@ extern "C" char kni_init() return -1; } + init_kni_tunprocess(); + if(g_kni_switch_info.maat_default_mode==0) { diff --git a/kni_entry.h b/kni_entry.h index 08ae72c..1e5b51f 100644 --- a/kni_entry.h +++ b/kni_entry.h @@ -73,6 +73,11 @@ //init profile info #define KNI_CONF_MAXLEN 1024 #define KNI_CONF_FILENAME "./kniconf/kni.conf" +#define KNI_MAIN_MODE "main" +#define KNI_FS_MODE "field_stat" +#define KNI_DYNMAAT_MODE "dynmic_maat" +#define KNI_STICMAAT_MODE "static_maat" +#define KNI_TUN_MODE "tun" #define KNI_CONF_MODE "Module" #define KNI_CONF_FILENAME_MAIN "./conf/main.conf" @@ -241,6 +246,7 @@ struct kni_switch_info int replace_switch; int sendpkt_mode; //0:mesa_sendpkt_option;1:socket int write_listq_switch; //0:no listq;1:has listq + int send_fds_mode; //0:has listq;1:no listq }; struct kni_http_project @@ -259,6 +265,7 @@ struct kni_var_comm int project_id; int kni_mode_cur; //0:work 1:bypass int thread_num; + int tun_threadnum; int fd_domain; int mark; char tun_name[KNI_CONF_MAXLEN]; @@ -337,6 +344,9 @@ struct kni_ratelimit_info //tcpall/udp_entry pmeinfo struct kni_pme_info { +//test + int tun_index; +//end int action; int cfg_id; int keyring_id; diff --git a/kni_intercept.c b/kni_intercept.c new file mode 100644 index 0000000..09fe08f --- /dev/null +++ b/kni_intercept.c @@ -0,0 +1,1487 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <net/if.h> +#include <sys/un.h> +#include <sys/ioctl.h> +#include <net/ethernet.h> +#include <netpacket/packet.h> +#include <linux/if_tun.h> +#include <time.h> +#include <assert.h> + +#include "kni_intercept.h" +#include "kni_entry.h" + + + + +extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len); +extern "C" int sendpacket_build_ethernet(unsigned char* dst,unsigned char* src,unsigned short type,const unsigned char* payload,int payload_s,unsigned char* buf); +extern "C" unsigned char MESA_dir_reverse(unsigned char route_dir); + + + +int kni_set_tlvinfo(char* buf,int buflen,struct kni_repaired_fds datainfo) +{ + int tlv_len = 0; + + struct kni_tlv_header header_info; + struct kni_tlv_info protocol_info; + struct kni_tlv_info keyring_info; + + header_info.magic = 0x4d5a; + header_info.counts = 2; + + protocol_info.type = KNI_TLV_TYPE_PROTOCOL; + protocol_info.len = sizeof(int); + + keyring_info.type = KNI_TLV_TYPE_KEYRING_ID; + keyring_info.len = sizeof(int); + + memcpy(buf+tlv_len,&header_info,sizeof(struct kni_tlv_header)); + tlv_len += sizeof(struct kni_tlv_header); + + memcpy(buf+tlv_len,&protocol_info,sizeof(struct kni_tlv_info)); + tlv_len += sizeof(struct kni_tlv_info); + memcpy(buf+tlv_len,&(datainfo.protocol),protocol_info.len); + tlv_len += protocol_info.len; + + memcpy(buf+tlv_len,&keyring_info,sizeof(struct kni_tlv_info)); + tlv_len += sizeof(struct kni_tlv_info); + memcpy(buf+tlv_len,&(datainfo.keyring),keyring_info.len); + tlv_len += keyring_info.len; + + + return tlv_len; + +} + + +int kni_send_fds(int socket,struct kni_repaired_fds to_send_fds) +{ + int flags=MSG_NOSIGNAL; + struct msghdr msg = {0}; + struct cmsghdr *cmsg; + char buf[CMSG_SPACE(KNI_SENDFD_NUM * sizeof(int))], dup[256]={0}; + memset(buf, 0, sizeof(buf)); + struct iovec io = { .iov_base = &dup, .iov_len = sizeof(dup) }; + + int dup_len = 256; + int fds[KNI_SENDFD_NUM]={0}; + fds[0] = to_send_fds.client_fd; + fds[1] = to_send_fds.server_fd; + + + dup_len = kni_set_tlvinfo(dup,dup_len,to_send_fds); + + msg.msg_iov = &io; + msg.msg_iovlen = 1; + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(KNI_SENDFD_NUM * sizeof(int)); + + memcpy ((int *) CMSG_DATA(cmsg), fds, KNI_SENDFD_NUM * sizeof (int)); + + if (sendmsg (socket, &msg, flags) < 0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_send_fds","sendmsg()error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + return 0; +} + + +int kni_unixdomain_sendinfo() +{ + int ret=0; + long datainfo_len = 0; + struct kni_repaired_fds to_send_fds; + + + struct timespec start, end; + long elapse=0; + + while(1) + { + datainfo_len = sizeof(to_send_fds); + + clock_gettime(CLOCK_MONOTONIC, &start); + + ret=MESA_lqueue_get_head(g_kni_structinfo.lqueue_send_fds,&to_send_fds,&datainfo_len); + if(ret==MESA_QUEUE_RET_QEMPTY) + { + continue; + } + if(ret<0) + { + assert(0); + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_qout_fd, 0, FS_OP_SET, elapse); + + + clock_gettime(CLOCK_MONOTONIC, &start); + + ret=kni_send_fds(g_kni_comminfo.fd_domain,to_send_fds); + if(ret<0) //check errno + { + kni_filestate2_set(0,COLUME_TCPREPAIR_SEND_ERR,0,2); + g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS; + close(to_send_fds.client_fd); + close(to_send_fds.server_fd); + return -1; + } + kni_filestate2_set(0,COLUME_TCPREPAIR_SEND_SUCC,0,2); + + close(to_send_fds.client_fd); + close(to_send_fds.server_fd); + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_sendfd, 0, FS_OP_SET, elapse); + + } + + return 0; +} + +int kni_unixdomain_connect() +{ + while(1) + { + g_kni_comminfo.fd_domain=kni_unixdomain_create(); + if(g_kni_comminfo.fd_domain<0) + { + sleep(1); + } + else + { + g_kni_comminfo.kni_mode_cur=KNI_MODE_WORK; + return 0; + } + } + + return 0; +} + +/******************************************************************************************************************** +name: +function: +return: +*********************************************************************************************************************/ +void* kni_unixdomain_process(void* arg) +{ + while(1) + { + if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS) + { + kni_unixdomain_connect(); + } + else if(g_kni_switch_info.send_fds_mode == 0) + { + kni_unixdomain_sendinfo(); + } + else + { + sleep(10); + } + } + + return 0; + +} + + + + +int kni_unixdomain_create() +{ + + int i_fd = 0; + struct sockaddr_un addr; + int i_addr_len = sizeof( struct sockaddr_un ); + + if ( ( i_fd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 ) +// if ( ( i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 ) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"kni_unixdomain_create():socket error,errno is %d,%s,,action:%s",errno,strerror(errno),KNI_ACTION_EXIT); + return -1; + } + +//fill socket adress structure with server's address + memset( &addr, 0, sizeof( addr ) ); + addr.sun_family = AF_UNIX; +// strncpy( addr.sun_path, serverpath, sizeof( addr.sun_path ) - 1 ); + strncpy( addr.sun_path, g_kni_comminfo.domain_path, sizeof( addr.sun_path ) - 1 ); + + + if ( connect( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 ) + { + close(i_fd); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"kni_unixdomain_create():connect error,errno is %d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT); + return -1; + } + + + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_unixdomain_create","domain socket connect succ! "); + return i_fd; +} + + + +int init_kni_unixdomain() +{ + pthread_t pid_pro_domain; + + g_kni_comminfo.fd_domain=kni_unixdomain_create(); + if(g_kni_comminfo.fd_domain<0) + { + g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS; + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"kni_unixdomain_create()error"); + } + + pthread_create(&pid_pro_domain,NULL,kni_unixdomain_process,NULL); + + return 0; + +} + + +int tun_set_queue(int fd, int enable) + { + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + + if (enable) + ifr.ifr_flags = IFF_ATTACH_QUEUE; + else + ifr.ifr_flags = IFF_DETACH_QUEUE; + + return ioctl(fd, TUNSETQUEUE, (void *)&ifr); + } + +int tun_error(int i,int* fds) +{ + + for (--i; i >= 0; i--) + { + close(fds[i]); + } + + return 0; +} + + + +/* Flags: IFF_TUN - TUN device (no Ethernet headers) + * IFF_TAP - TAP device + * + * IFF_NO_PI - Do not provide packet information + * IFF_MULTI_QUEUE - Create a queue of multiqueue device + */ +int tun_alloc_mq(char *dev, int queues, int *fds,char* tun_path) +{ + int i=0; + int err=0; + int fd; + int flag=0; + struct ifreq ifr; + + +// char *clonedev = (char*)"/dev/net/tun"; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE; + if (*dev) + { + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + } + + for (i = 0; i < queues; i++) + { + if ((fd = open(tun_path, O_RDWR)) < 0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"tun_alloc_mq():open error,errno is:%d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT); + tun_error(i,fds); + return -1; + } + err = ioctl(fd, TUNSETIFF, (void *)&ifr); + if (err) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"tun_alloc_mq():ioctl error,errno is:%d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT); + close(fd); + tun_error(i,fds); + return -1; + } + +//20180618 add set noblock + flag= fcntl(fd, F_GETFL, 0); + if(flag<0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"fcntl():getfl error,errno is:%d,%s",errno,strerror(errno)); + } + + if( fcntl( fd, F_SETFL, flag|O_NONBLOCK ) < 0 ) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"fcntl():setfl error,errno is:%d,%s",errno,strerror(errno)); + } + +//end + + fds[i] = fd; + } + return 0; +} + + + + int init_kni_tun() + { + int ret; + + char tun_path[KNI_CONF_MAXLEN]={0}; + + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_TUN_MODE,(char*)"tun_path",tun_path,KNI_CONF_MAXLEN,"/dev/net/tun"); + MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_TUN_MODE,(char*)"tun_name",g_kni_comminfo.tun_name,KNI_CONF_MAXLEN,"tun0"); + + +// g_kni_comminfo.tun_threadnum=g_iThreadNum; + if(g_kni_comminfo.tun_threadnum<=0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"thread_num:%d,action:%s",g_kni_comminfo.thread_num,KNI_ACTION_EXIT); + return -1; + } + + g_kni_comminfo.fd_tun=(int*)malloc(g_kni_comminfo.tun_threadnum*sizeof(int)); + memset(g_kni_comminfo.fd_tun,0,g_kni_comminfo.tun_threadnum*sizeof(int)); + + ret=tun_alloc_mq(g_kni_comminfo.tun_name,g_kni_comminfo.tun_threadnum,g_kni_comminfo.fd_tun,tun_path); + + return ret; + +} + + +char kni_add_lqueue(int addrtype,int thread_seq,char* send_buf,int send_buflen,const struct streaminfo* pstream,int index) +{ + + char ret=APP_STATE_DROPPKT|APP_STATE_GIVEME; + int listq_ret = 0; + struct kni_inject_pkt to_inject; + + to_inject.addr_type = addrtype; + to_inject.buflen = send_buflen; + to_inject.buf = (char*)malloc(send_buflen); + memcpy(to_inject.buf,send_buf,send_buflen); + clock_gettime(CLOCK_MONOTONIC, &(to_inject.start)); + + listq_ret=MESA_lqueue_join_tail(g_kni_structinfo.lqueue_write_tun[index],(void*)&to_inject,sizeof(to_inject)); + if(listq_ret <0) + { + kni_htable_del(pstream,(const void*)send_buf); + + free(to_inject.buf); + to_inject.buf = NULL; + + ret=APP_STATE_DROPPKT|APP_STATE_DROPME; + kni_filestate2_set(thread_seq,COLUME_ADD_LQUEUE_ERR,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDFD,"kni_add_lqueue() error,ret:%d",ret); + return ret; + } + + kni_filestate2_set(thread_seq,COLUME_ADD_LQUEUE_SUCC,0,1); + + return ret; + +} + + +int kni_sendpkt_sockraw(int thread_seq,int iplen,char* ip,struct stream_tuple4_v4* ipv4_addr,int iprever_flag,int routdir,uchar* smac,uchar* dmac) +{ + if((routdir!=0)&&(routdir!=1)) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,"kni_sendpkt_sockraw","routdir:%d",routdir); + return -1; + } + + int ret=0; + int buflen=iplen+KNI_ETHER_LEN; + + unsigned char buf[2000]={0}; + unsigned short eth_type=0x0800; + + uchar* tmp_smac; + uchar* tmp_dmac; + + + struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)buf; + unsigned short eth_type_v6 = 0x86dd; + + char* if_name=NULL; + if(iprever_flag==0) + { + tmp_smac=smac; + tmp_dmac=dmac; + } + else + { + tmp_smac=dmac; + tmp_dmac=smac; + } + + if_name=g_kni_cardname[1-routdir]; + + struct ifreq ifr; + size_t ifname_len=strlen(if_name); + if(ifname_len<sizeof(ifr.ifr_name)) + { + memset(ifr.ifr_name,0,IFNAMSIZ); + memcpy(ifr.ifr_name,if_name,ifname_len); + } + else + { + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"interface name :%s is too long\n",if_name); + return -1; + } + + if(-1==ioctl(g_kni_comminfo.fd_sendpkt[thread_seq],SIOCGIFINDEX,&ifr)) + { + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"get if index error:%d,%s,name:%d",errno,strerror(errno),if_name); + return -1; + } + + struct sockaddr_ll addr={0}; + addr.sll_family=AF_PACKET; + addr.sll_halen=ETHER_ADDR_LEN; + addr.sll_ifindex=ifr.ifr_ifindex; + addr.sll_protocol=htons(ETH_P_IP); + memcpy(addr.sll_addr,tmp_dmac,ETHER_ADDR_LEN); + + + if(ioctl(g_kni_comminfo.fd_sendpkt[thread_seq],SIOCGIFHWADDR,&ifr)==-1) + { + return -1; + } + + if((ipv6_hdr->ip6_flags[0] & 0xF0) == 0x60) + { + sendpacket_build_ethernet((unsigned char*)tmp_dmac,(unsigned char*)tmp_smac,eth_type_v6,(const unsigned char*)ip,iplen,(unsigned char*)buf); + + } + else + { + sendpacket_build_ethernet((unsigned char*)tmp_dmac,(unsigned char*)tmp_smac,eth_type,(const unsigned char*)ip,iplen,(unsigned char*)buf); + } + + + ret=sendto(g_kni_comminfo.fd_sendpkt[thread_seq],buf,buflen,0,(struct sockaddr*)&addr,sizeof(addr)); + if(ret<0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"sendto() error,errno:%d,msg:%s!",errno,strerror(errno)); + } + + return ret; + +} + + + + + +int kni_keepalive_replay_v6(struct stream_tuple4_v6* ipv6_addr,int iprever_flag,struct kni_htable_datainfo* datainfo,void* a_packet,int iplen,int thread_seq) +{ + if(!g_kni_switch_info.replay_win_update) + { + return 0; + } + + int index=1-iprever_flag; + + struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)a_packet; + +//ipv6 has opt not process 20181115 modify + if((ipv6_hdr != NULL) && (ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP)) + { + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"kni_keepalive_replay_v6():ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP,not send window probe replay"); + return 0; + } +//end + + struct kni_tcp_hdr* tcphdr=(struct kni_tcp_hdr*)((unsigned char*)a_packet + sizeof(struct kni_ipv6_hdr)); + + struct kni_wndpro_reply_info* tcpinfo=&(datainfo->lastpkt_info[index]); + + struct kni_ipv6_hdr* snd_iphdr=NULL; + struct kni_tcp_hdr* snd_tcphdr=NULL; + char* sendbuf=(char*)malloc(iplen); + memcpy(sendbuf,a_packet,iplen); + + snd_iphdr=(struct kni_ipv6_hdr*)sendbuf; + snd_tcphdr=(struct kni_tcp_hdr*)((unsigned char*)snd_iphdr + sizeof(struct kni_ipv6_hdr)); + + + memcpy(&(snd_iphdr->ip6_src),&(ipv6_hdr->ip6_dst),sizeof(struct in6_addr)); + memcpy(&(snd_iphdr->ip6_dst),&(ipv6_hdr->ip6_src),sizeof(struct in6_addr)); + + + snd_tcphdr->th_sport=tcphdr->th_dport; + snd_tcphdr->th_dport=tcphdr->th_sport; + snd_tcphdr->th_seq=htonl(tcpinfo->seq+tcpinfo->len); + snd_tcphdr->th_ack=htonl(tcpinfo->ack); + + + if(tcpinfo->syn_flag==1) + { + snd_tcphdr->th_seq=htonl(ntohl(snd_tcphdr->th_seq)+1); + } + sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,htons(ipv6_hdr->ip6_payload_len)); +// sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct kni_ipv6_hdr)); + +// tun_write_data(g_kni_comminfo.fd_tun[thread_seq],sendbuf,iplen,NULL,thread_seq); + tun_write_data(g_kni_comminfo.fd_tun[thread_seq],sendbuf,iplen,NULL,thread_seq); + + + + kni_log_debug(RLOG_LV_DEBUG,(char*)"win_update",a_packet,(char*)"recv tcp_repair windows update,and replay"); + + free(sendbuf); + sendbuf=NULL; + + datainfo->wndprob_flag[index]=1; + + kni_filestate2_set(thread_seq,COLUME_REPLAY_WINDOW,0,1); + + + return 1; + + +} + + + +int kni_keepalive_replay(struct stream_tuple4_v4* ipv4_addr,int iprever_flag,struct kni_htable_datainfo* datainfo,void* a_packet,int iplen,int thread_seq) +{ + + if(!g_kni_switch_info.replay_win_update) + { + return 0; + } + + + int index=1-iprever_flag; + + struct ip* iphdr=(struct ip*)a_packet; + struct tcphdr* tcphdr=(struct tcphdr*)((char*)iphdr+4*(iphdr->ip_hl)); + struct kni_wndpro_reply_info* tcpinfo=&(datainfo->lastpkt_info[index]); + + struct ip* snd_iphdr=NULL; + struct tcphdr* snd_tcphdr=NULL; + char* sendbuf=(char*)malloc(iplen); + memcpy(sendbuf,a_packet,iplen); + + snd_iphdr=(struct ip*)sendbuf; + snd_tcphdr=(struct tcphdr*)((char*)snd_iphdr+4*(snd_iphdr->ip_hl)); + + (snd_iphdr->ip_src).s_addr=(iphdr->ip_dst).s_addr; + (snd_iphdr->ip_dst).s_addr=(iphdr->ip_src).s_addr; + + snd_tcphdr->source=tcphdr->dest; + snd_tcphdr->dest=tcphdr->source; + snd_tcphdr->seq=htonl(tcpinfo->seq+tcpinfo->len); + snd_tcphdr->ack_seq=htonl(tcpinfo->ack); + + + if(tcpinfo->syn_flag==1) + { + snd_tcphdr->seq=htonl(ntohl(snd_tcphdr->seq)+1); + } + + sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,(iplen-4*(iphdr->ip_hl))); + sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip)); + +// tun_write_data(g_kni_comminfo.fd_tun[thread_seq],sendbuf,iplen,NULL,thread_seq); + tun_write_data(g_kni_comminfo.fd_tun[thread_seq],sendbuf,iplen,NULL,thread_seq); + + kni_log_debug(RLOG_LV_DEBUG,(char*)"win_update",a_packet,(char*)"recv tcp_repair windows update,and replay"); + + free(sendbuf); + sendbuf=NULL; + + datainfo->wndprob_flag[index]=1; + + kni_filestate2_set(thread_seq,COLUME_REPLAY_WINDOW,0,1); + + + return 1; + + +} + + + +long kni_readtun_htable_cb_v6(void* data,const unsigned char* key,unsigned int size,void* user_arg) +{ + long result=0; + struct stream_tuple4_v6* ipv6_addr=(struct stream_tuple4_v6*)key; + struct args_read_tun* args=(struct args_read_tun*)user_arg; + struct kni_htable_datainfo* datainfo=(struct kni_htable_datainfo*)data; + + if(datainfo!=NULL) + { + memcpy(args->smac,datainfo->smac,KNI_MACADDR_LEN); + memcpy(args->dmac,datainfo->dmac,KNI_MACADDR_LEN); + if(args->iprevers==0) + { + args->routdir=datainfo->route_dir; + } + else + { + if(g_kni_switch_info.sendpkt_mode == 1) + { + args->routdir=1-datainfo->route_dir; + + } + else + { + args->routdir=MESA_dir_reverse(datainfo->route_dir); + } + } + + if(datainfo->wndprob_flag[1-args->iprevers]>0) + { + result=1; + } + else + { + kni_keepalive_replay_v6(ipv6_addr,args->iprevers,datainfo,args->a_packet,args->iplen,args->thread_seq); + result=1; + } + } + + return result; +} + + + +long kni_readtun_htable_cb_v4(void* data,const unsigned char* key,unsigned int size,void* user_arg) +{ + long result=0; + struct stream_tuple4_v4* ipv4_addr=(struct stream_tuple4_v4*)key; + struct args_read_tun* args=(struct args_read_tun*)user_arg; + struct kni_htable_datainfo* datainfo=(struct kni_htable_datainfo*)data; + + if(datainfo!=NULL) + { + memcpy(args->smac,datainfo->smac,KNI_MACADDR_LEN); + memcpy(args->dmac,datainfo->dmac,KNI_MACADDR_LEN); + if(args->iprevers==0) + { + args->routdir=datainfo->route_dir; + } + else + { + if(g_kni_switch_info.sendpkt_mode == 1) + { + args->routdir=1-datainfo->route_dir; + + } + else + { + args->routdir=MESA_dir_reverse(datainfo->route_dir); + } + + } + + if(datainfo->wndprob_flag[1-args->iprevers]>0) + { + result=1; + } + else + { + kni_keepalive_replay(ipv4_addr,args->iprevers,datainfo,args->a_packet,args->iplen,args->thread_seq); + result=1; + } + + + + } +#ifdef KNI_DEBUG_TCPREPAIR + else if(ipv4_addr->saddr==1698867392) + { + printf("sip is 192.168.66.101\n"); + args->smac[0]=0x18; + args->smac[1]=0x66; + args->smac[2]=0xda; + args->smac[3]=0xe5; + args->smac[4]=0xfa; + args->smac[5]=0xa1; + + args->dmac[0]=0xe8; + args->dmac[1]=0x61; + args->dmac[2]=0x1f; + args->dmac[3]=0x13; + args->dmac[4]=0x70; + args->dmac[5]=0x7a; + result=1; + } + else + { + kni_log_debug(RLOG_LV_INFO,"htable_cb",(void*)args->a_packet,(char*)"read_tun,data=NULL,sip not 192.168.66.101"); + + } +#endif + return result; +} + + + + + +int kni_process_readdata(int thread_seq,int sendpkt_threadid,int buflen,char* buf) +{ + int iprever_flag=0; + long result=0; + + struct ip* ipv4_hdr=(struct ip*)buf; + struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)buf; + struct stream_tuple4_v4 ipv4_addr; + struct stream_tuple4_v6 ipv6_addr; + + struct args_read_tun args; + + if(ipv4_hdr->ip_v==4) + { + iprever_flag=kni_get_ipaddr_v4((void*)buf,&ipv4_addr); + + args.a_packet=buf; + args.iplen=buflen; + args.iprevers=iprever_flag; + args.thread_seq=thread_seq; + + MESA_htable_search_cb(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),kni_readtun_htable_cb_v4,(void*)&args,&result); + if(result==1) + { + kni_filestate2_set(thread_seq,COLUME_SEND_PKT,0,1); + + if(g_kni_switch_info.sendpkt_mode == 1) + { + kni_sendpkt_sockraw(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac); + } + else + { + MESA_sendpacket_iplayer_options(thread_seq,buf,buflen,args.routdir,NULL,0); + } + } + else + { + kni_log_debug(RLOG_LV_FATAL,(char*)"kni_readtun_htable_cb_v4",buf,(const char*)"kni_readtun_htable_cb_v4 not found!"); + kni_filestate2_set(thread_seq,COLUME_DROP_NOIN_HTABLE,0,1); + } + + } + else if((ipv6_hdr->ip6_flags[0] & 0xF0) == 0x60) + { + iprever_flag=kni_get_ipaddr_v6((void*)buf,&ipv6_addr); + + args.a_packet=buf; + args.iplen=buflen; + args.iprevers=iprever_flag; + args.thread_seq=thread_seq; + + MESA_htable_search_cb(g_kni_structinfo.htable_to_tun_v6,(unsigned char*)&ipv6_addr,sizeof(struct stream_tuple4_v6),kni_readtun_htable_cb_v6,(void*)&args,&result); + if(result==1) + { + kni_filestate2_set(thread_seq,COLUME_SEND_PKT,0,1); + + if(g_kni_switch_info.sendpkt_mode == 1) + { + kni_sendpkt_sockraw(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac); + } + else + { + MESA_sendpacket_ipv6_layer_options(thread_seq,buf,buflen,args.routdir,NULL,0); + } + + } + else + { + kni_filestate2_set(thread_seq,COLUME_DROP_NOIN_HTABLE,0,1); + } + + } + else + { + kni_filestate2_set(thread_seq,COLUME_DROP_NOTIPV46_TUN,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"kni_readdata,not ipv4 and not ipv6!"); + + } + + return 0; + +} + +int kni_process_writedata(int thread_seq) +{ + int ret = 0; + struct kni_inject_pkt datainfo; + long datainfo_len = sizeof(datainfo); + + struct timespec end; + long elapse=0; + + ret=MESA_lqueue_get_head(g_kni_structinfo.lqueue_write_tun[thread_seq],&datainfo,&datainfo_len); + if(ret == MESA_QUEUE_RET_QEMPTY) + { + return 0; + } + else if(ret<0) + { + kni_filestate2_set(thread_seq,COLUME_GET_LQUEUE_ERR,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"kni_process_writedata","MESA_lqueue_try_get_tail() error!ret:%d,datalen:%d\n",ret,datainfo_len); + return -1; + } + else + { + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-datainfo.start.tv_sec)*1000000+(end.tv_nsec-datainfo.start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_qout_pkt,0,FS_OP_SET, elapse); + + + kni_filestate2_set(thread_seq,COLUME_GET_LQUEUE_SUCC,0,1); + + tun_write_data_listq(g_kni_comminfo.fd_tun[thread_seq],datainfo.buf,datainfo.buflen,thread_seq); + + free(datainfo.buf); + datainfo.buf = NULL; + } + + return 0; +} + + +int tun_read_data(int fd,char* recv_buf,int max_buflen) +{ + int recv_len=0; + + int ret=0; + int max_fd = 0; + + if(g_kni_switch_info.write_listq_switch == 0) + { + fd_set alive_readfd; + struct timeval timeout; + memset(&timeout,0,sizeof(timeout)); + + + FD_ZERO(&alive_readfd); + FD_SET(fd, &alive_readfd); + max_fd = fd; + + // ret = select(max_fd + 1, &alive_readfd, NULL, NULL, &timeout); + ret = select(max_fd + 1, &alive_readfd, NULL, NULL, NULL); + if (ret < 0) + { + // MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL, "keep_alive_action function", "select function errno %d is %s!", errno, strerror(errno)); + return 0; + } + } + + recv_len = read(fd, recv_buf, KNI_MAX_BUFLEN); + if(recv_len <0) + { +// MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"tun_read_data error %d, %s\n",errno,strerror(errno)); + return -1; + } + else + { + return recv_len; + } + + return 0; +} + + + +char tun_write_data_listq(int fd,char* send_buf,int send_buflen,int thread_seq) +{ + char ret=APP_STATE_DROPPKT|APP_STATE_GIVEME; + int succ_sendlen=0; + + struct timespec start, end; + long elapse=0; + clock_gettime(CLOCK_MONOTONIC, &start); + + succ_sendlen = write(fd, send_buf,send_buflen); + if(succ_sendlen<0) + { + kni_filestate2_set(thread_seq,COLUME_WRITE_TUN_ERR,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"write() error %d, %s",errno,strerror(errno)); + ret=APP_STATE_DROPPKT|APP_STATE_DROPME; + } + else if(succ_sendlen<send_buflen) + { + kni_filestate2_set(thread_seq,COLUME_WRITE_TUN_ERR,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"succ_sendlen is %d,send_buflen is %d",succ_sendlen,send_buflen); + } + else + { + kni_filestate2_set(thread_seq,COLUME_WRITE_TUN_SUCC,0,1); + } + + kni_filestate2_set(thread_seq,COLUME_TUN_WRITE,0,1); + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_tun_write, 0, FS_OP_SET, elapse); + + return ret; + +} + + + + +char tun_write_data(int fd,char* send_buf,int send_buflen,struct streaminfo* pstream,int thread_seq) +{ + char ret=APP_STATE_DROPPKT|APP_STATE_GIVEME; + int succ_sendlen=0; + + struct timespec start, end; + long elapse=0; + clock_gettime(CLOCK_MONOTONIC, &start); + + succ_sendlen = write(fd, send_buf,send_buflen); + if((succ_sendlen<0)&&(pstream!=NULL)) + { + kni_htable_del(pstream,(const void*)send_buf); + + kni_filestate2_set(thread_seq,COLUME_WRITE_TUN_ERR,0,1); +// MESA_kill_tcp(pstream,(const void*)send_buf); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"write() error %d, %s",errno,strerror(errno)); + ret=APP_STATE_DROPPKT|APP_STATE_DROPME; + } + else if(succ_sendlen<send_buflen) + { + kni_htable_del(pstream,(const void*)send_buf); + + kni_filestate2_set(thread_seq,COLUME_WRITE_TUN_ERR,0,1); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"succ_sendlen is %d,send_buflen is %d",succ_sendlen,send_buflen); + } + + kni_filestate2_set(thread_seq,COLUME_TUN_WRITE,0,1); + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_tun_write, 0, FS_OP_SET, elapse); + + return ret; + +} + + + +int tun_write_data_v6(int fd,char* send_buf,int send_buflen) +{ + int succ_sendlen=0; + + succ_sendlen = write(fd, send_buf,send_buflen); + if(succ_sendlen<0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"write() error!msg is %s",strerror(errno)); + } + else if(succ_sendlen<send_buflen) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"succ_sendlen is %d,send_buflen is %d",succ_sendlen,send_buflen); + } + + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,KNI_MODULE_WRITETUN,"write to tun completed,,send_buflen is %d",succ_sendlen); + + return succ_sendlen; + +} + + + +/******************************************************************************************************************** +name: +function: +return: +*********************************************************************************************************************/ +void* pthread_process_tun(void* arg) +{ + int thread_seq=*(int*)arg; + int recv_len=0; + char recv_buf[KNI_MAX_BUFLEN] = {0}; + + int sendpkt_threadid=0; + int sendpkt_threadid_len = sizeof(int); + long elapse=0; + sapp_get_platform_opt(SPO_INDEPENDENT_THREAD_ID,&sendpkt_threadid,&sendpkt_threadid_len); + + struct timespec start, end; + + while(1) + { + if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS) + { + sleep(KNI_USLEEP_TIME); + continue; + } +//write to run + if(g_kni_switch_info.write_listq_switch == 1) + { + kni_process_writedata(thread_seq); + } + +//end + +//read from tun + clock_gettime(CLOCK_MONOTONIC, &start); + recv_len=0; + + recv_len=tun_read_data(g_kni_comminfo.fd_tun[thread_seq],recv_buf, KNI_MAX_BUFLEN); + if(recv_len <0) + { +// MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_READTUN,"tun_read_data()error,recv_len:%d",recv_len); + } + else if(recv_len>0) + { + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_tun_read, 0, FS_OP_SET, elapse); + start=end; + kni_filestate2_set(thread_seq,COLUME_TUN_READ,0,1); + kni_process_readdata(thread_seq,sendpkt_threadid,recv_len,recv_buf); + clock_gettime(CLOCK_MONOTONIC, &end); + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_forward, 0, FS_OP_SET, elapse); + } +//end + } + + return 0; + +} + + + + +int tcprepair_get_addr(void** client_addr,void** server_addr,const struct layer_addr* addr,const void* a_packet) +{ + struct ip* ipv4_hdr = NULL; + struct kni_ipv6_hdr* ipv6_hdr = NULL; + struct kni_tcp_hdr* tcphdr=NULL; + + struct sockaddr_in* client_addr_v4; + struct sockaddr_in* server_addr_v4; + + struct sockaddr_in6* client_addr_v6; + struct sockaddr_in6* server_addr_v6; + + if(addr->addrtype == ADDR_TYPE_IPV4) + { + ipv4_hdr = (struct ip*)a_packet; + tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl)); + + client_addr_v4 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); + memset(client_addr_v4,0,sizeof(struct sockaddr_in)); + client_addr_v4->sin_family = AF_INET; + client_addr_v4->sin_port = tcphdr->th_sport; + client_addr_v4->sin_addr.s_addr = (ipv4_hdr->ip_src).s_addr; + + server_addr_v4 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); + memset(server_addr_v4,0,sizeof(struct sockaddr_in)); + server_addr_v4->sin_family = AF_INET; + server_addr_v4->sin_port = tcphdr->th_dport; + server_addr_v4->sin_addr.s_addr = (ipv4_hdr->ip_dst).s_addr; + + *client_addr = client_addr_v4; + *server_addr = server_addr_v4; + } + else if(addr->addrtype == ADDR_TYPE_IPV6) + { + ipv6_hdr = (struct kni_ipv6_hdr*)a_packet; + tcphdr = (struct kni_tcp_hdr*)((unsigned char*)a_packet + sizeof(struct kni_ipv6_hdr)); + + client_addr_v6 = (struct sockaddr_in6*)malloc(sizeof(struct sockaddr_in6)); + memset(client_addr_v6,0,sizeof(struct sockaddr_in6)); + client_addr_v6->sin6_family = AF_INET6; + client_addr_v6->sin6_port = tcphdr->th_sport; + memcpy(&(client_addr_v6->sin6_addr),&(ipv6_hdr->ip6_src),sizeof(struct in6_addr)); + + server_addr_v6 = (struct sockaddr_in6*)malloc(sizeof(struct sockaddr_in6)); + memset(server_addr_v6,0,sizeof(struct sockaddr_in)); + server_addr_v6->sin6_family = AF_INET6; + server_addr_v6->sin6_port = tcphdr->th_dport; + memcpy(&(server_addr_v6->sin6_addr),&(ipv6_hdr->ip6_dst),sizeof(struct in6_addr)); + + *client_addr = client_addr_v6; + *server_addr = server_addr_v6; + } + else + { + return -1; + } + + return 0; +} + + + +int tcprepair_free_addr(struct sockaddr* client_addr,struct sockaddr* server_addr) +{ + if(client_addr != NULL) + { + free(client_addr); + client_addr =NULL; + } + + if(server_addr != NULL) + { + free(server_addr); + server_addr = NULL; + } + + return 0; +} + + +int tcprepair_get_state(int curdir,const struct layer_addr* addr,struct kni_tcp_state* fake_client,struct kni_tcp_state* fake_server,const void* a_packet,struct kni_pme_info* pmeinfo) +{ + + struct ip* ipv4_hdr = NULL; + struct kni_tcp_hdr* tcphdr=NULL; + + if(addr->addrtype==ADDR_TYPE_IPV4) + { + ipv4_hdr = (struct ip*)a_packet; + tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl)); + } + else if(addr->addrtype==ADDR_TYPE_IPV6) + { + tcphdr = (struct kni_tcp_hdr*)((unsigned char*)a_packet + sizeof(struct kni_ipv6_hdr)); + } + + fake_client->seq=ntohl(tcphdr->th_seq); + fake_client->ack=ntohl(tcphdr->th_ack); + fake_client->mss_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].mss; + fake_client->mss_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].mss; + fake_client->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].wnscal; + fake_client->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].wnscal; + fake_client->sack_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack; + fake_client->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack; + fake_client->timestamps_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].timestamps; + fake_client->timestamps_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; + + fake_server->seq=ntohl(tcphdr->th_ack); + fake_server->ack=ntohl(tcphdr->th_seq); + fake_server->mss_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].mss; + fake_server->mss_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].mss; + fake_server->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].wnscal; + fake_server->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].wnscal; + fake_server->sack_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack; + fake_server->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack; + fake_server->timestamps_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; + fake_server->timestamps_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; + + return 0; +} + + + +int tcprepair_set_state(int sk,struct kni_tcp_state* tcp,struct sockaddr* client_addr,struct sockaddr* server_addr,int addr_type) +{ + int val,yes=1, onr = 0; + int temp_mark=0; + + socklen_t mark_len =sizeof(temp_mark); + + struct tcp_repair_opt opts[KNI_TCPREPAIR_OPT_NUM]; + + if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &yes, sizeof(yes))==-1) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + + if (setsockopt(sk, SOL_IP, IP_TRANSPARENT, &yes, sizeof(yes)) < 0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() IP_TRANSPARENT error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + + if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() SO_REUSEADDR error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + if(setsockopt(sk,SOL_SOCKET,SO_MARK,&(g_kni_comminfo.mark),sizeof(g_kni_comminfo.mark))==-1) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() SO_MARK error,errno:%d,%s",errno,strerror(errno)); + return -1; + + } + getsockopt(sk,SOL_SOCKET,SO_MARK,&temp_mark,&mark_len); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,"tcprepair_set_state","setsockopt() fd :%d,SO_MARK:%d",sk,temp_mark); + /* ============= Restore TCP properties ==================*/ + val = TCP_SEND_QUEUE; + if (setsockopt(sk, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_QUEUE,TCP_SEND_QUEUE error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + val = tcp->seq; + if (setsockopt(sk, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + val = TCP_RECV_QUEUE; + if (setsockopt(sk, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_QUEUE,TCP_RECV_QUEUE error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + val = tcp->ack; + if (setsockopt(sk, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + + /* ============= Bind and connect ================ */ + if(addr_type == ADDR_TYPE_IPV4) + { + if (bind(sk,client_addr, sizeof(struct sockaddr))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","bind() error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + if (connect(sk,server_addr, sizeof(struct sockaddr))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","connect() error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + } + else if (addr_type == ADDR_TYPE_IPV6) + { + if (bind(sk,client_addr, sizeof(struct sockaddr_in6))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","bind() error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + if (connect(sk,server_addr, sizeof(struct sockaddr_in6))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","connect() error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + } + + + if((tcp->wscale_dst)&&(tcp->wscale_src)) + { + opts[onr].opt_code = TCPOPT_WINDOW; + opts[onr].opt_val = tcp->wscale_dst+ (tcp->wscale_src<< 16); + onr++; + } + + + opts[onr].opt_code = TCPOPT_MAXSEG; + opts[onr].opt_val = (tcp->mss_src<tcp->mss_dst)?tcp->mss_src:tcp->mss_dst; + onr++; + + if((tcp->sack_src)&&(tcp->sack_dst)) + { + opts[onr].opt_code = TCPOPT_SACK_PERMITTED; + opts[onr].opt_val = 0; + onr++; + } + + +//test + + struct sockaddr_in* client_addr_v4 = (struct sockaddr_in*)client_addr; + struct sockaddr_in* server_addr_v4 = (struct sockaddr_in*)server_addr; + if(addr_type == ADDR_TYPE_IPV4) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,"tcprepair_set_option","sip:%d,dip:%d,sport:%d,dport:%d,wscale:%d,mss:%d", + ntohl(client_addr_v4->sin_addr.s_addr),ntohl(server_addr_v4->sin_addr.s_addr),ntohs(client_addr_v4->sin_port),ntohs(server_addr_v4->sin_port),opts[0].opt_val,opts[1].opt_val); + } + +//test end + + if (setsockopt(sk, SOL_TCP, TCP_REPAIR_OPTIONS,opts, onr * sizeof(struct tcp_repair_opt)) < 0) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_OPTIONS error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + val = 0; + if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &val, sizeof(val))) + { + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR close error,errno:%d,%s",errno,strerror(errno)); + return -1; + } + + return 0; + + +} + + + + +int tcp_repair_process(const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo,int protocol) +{ + kni_filestate2_set(pstream->threadnum,COLUME_TCPREPAIR_TOTAL,0,2); + + int ret=0; + struct kni_repaired_fds repaired_fds; + + int fd_client,fd_server; + struct kni_tcp_state fake_client; + struct kni_tcp_state fake_server; + + struct sockaddr* client_addr = NULL; + struct sockaddr* server_addr = NULL; + + struct timespec start, end; + long elapse = 0; + + + if(pstream->addr.addrtype==ADDR_TYPE_IPV4) + { + fd_client = socket(AF_INET, SOCK_STREAM, 0); + fd_server = socket(AF_INET, SOCK_STREAM, 0); + } + else if(pstream->addr.addrtype==ADDR_TYPE_IPV6) + { + fd_client = socket(AF_INET6, SOCK_STREAM, 0); + fd_server = socket(AF_INET6, SOCK_STREAM, 0); + } + else + { + assert(0); + } + if ((fd_client < 0)||(fd_server<0)) + { + kni_filestate2_set(pstream->threadnum,COLUME_TCPREPAIR_SOCKET_ERR,0,2); + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","socket() error"); + return -1; + } + + + tcprepair_get_addr((void**)&client_addr,(void**)&server_addr,&(pstream->addr),a_packet); + tcprepair_get_state(pstream->curdir,&(pstream->addr),&fake_client,&fake_server,(void*)a_packet,pmeinfo); + + + ret=tcprepair_set_state(fd_client,&fake_server,server_addr,client_addr,pstream->addr.addrtype); + if(ret<0) + { + kni_filestate2_set(pstream->threadnum,COLUME_TCPREPAIR_ERROR,0,2); + close(fd_client); + close(fd_server); + + tcprepair_free_addr(client_addr,server_addr); +// MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","fd_client tcprepair_set_state() error,dropme and fwdpkt"); + kni_log_debug(RLOG_LV_FATAL,(char*)"tcprepair_set_state",a_packet,(const char*)"fd_client tcprepair_set_state() error,dropme and fwdpkt"); + return -1; + } + + ret=tcprepair_set_state(fd_server,&fake_client,client_addr,server_addr,pstream->addr.addrtype); + if(ret<0) + { + kni_filestate2_set(pstream->threadnum,COLUME_TCPREPAIR_ERROR,0,2); + close(fd_client); + close(fd_server); + + tcprepair_free_addr(client_addr,server_addr); +// MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","fd_server tcprepair_set_state() error,dropme and fwdpkt"); + kni_log_debug(RLOG_LV_FATAL,(char*)"tcprepair_set_state",a_packet,(const char*)"fd_server tcprepair_set_state() error,dropme and fwdpkt"); + return -1; + } + + tcprepair_free_addr(client_addr,server_addr); + + repaired_fds.client_fd = fd_client; + repaired_fds.server_fd = fd_server; + repaired_fds.protocol = pmeinfo->protocol; + repaired_fds.keyring = pmeinfo->keyring_id; + + if(g_kni_switch_info.send_fds_mode == 0) + { + ret=MESA_lqueue_join_tail(g_kni_structinfo.lqueue_send_fds,(void*)&repaired_fds,sizeof(repaired_fds)); + if(ret <0) + { + kni_filestate2_set(pstream->threadnum,COLUME_TCPREPAIR_JOINLQ_ERR,0,2); + + close(fd_client); + close(fd_server); + + MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDFD,"MESA_lqueue_try_join_head() error,ret:%d",ret); + } + } + else + { + clock_gettime(CLOCK_MONOTONIC, &start); + + ret=kni_send_fds(g_kni_comminfo.fd_domain,repaired_fds); + if(ret<0) + { + kni_filestate2_set(0,COLUME_TCPREPAIR_SEND_ERR,0,2); + g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS; + } + else + { + kni_filestate2_set(0,COLUME_TCPREPAIR_SEND_SUCC,0,2); + } + + close(fd_client); + close(fd_server); + clock_gettime(CLOCK_MONOTONIC, &end); + + elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000; + FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_sendfd, 0, FS_OP_SET, elapse); + + } + + pmeinfo->client_fd = fd_client; + pmeinfo->server_fd = fd_server; + + return ret; + +} + + + + + + diff --git a/kni_intercept.h b/kni_intercept.h new file mode 100644 index 0000000..b740718 --- /dev/null +++ b/kni_intercept.h @@ -0,0 +1,24 @@ +#ifndef KNI_CONNECT_H +#define KNI_CONNECT_H + + +#define KNI_SENDFD_NUM 2 + +int kni_send_fds(int socket, int *fds, int n,int protocol); +char tun_write_data(int fd,char* send_buf,int send_buflen,struct streaminfo* pstream,int thread_seq); +char tun_write_data_listq(int fd,char* send_buf,int send_buflen,int thread_seq); + + +int kni_unixdomain_create(); +int init_kni_unixdomain(); +int init_kni_tun(); + +void* pthread_process_tun(void* arg); +char kni_add_lqueue(int addrtype,int thread_seq,char* send_buf,int send_buflen,const struct streaminfo* pstream,int index); + +int tcp_repair_process(const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo,int protocol); + + + +#endif + |
