From 6bdd3d0ed0f756b5cdcd62c7e1cb946a55af4391 Mon Sep 17 00:00:00 2001 From: liuyang Date: Mon, 26 Nov 2018 09:10:54 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=89=B9=E9=87=8Fwrite=E5=88=B0tun?= =?UTF-8?q?=EF=BC=8C=E6=B5=81=E9=87=8F=E5=8F=AF=E4=BB=A5=E5=88=B0=E8=BE=BE?= =?UTF-8?q?4-5Gbps=E5=B7=A6=E5=8F=B3=EF=BC=8C=E4=BD=86=E6=98=AF=E4=BB=8D?= =?UTF-8?q?=E6=9C=89=E4=B8=A2=E5=8C=85=E3=80=822=E3=80=81=E7=BB=86?= =?UTF-8?q?=E8=8A=82=E5=8F=82=E6=95=B0=E5=BE=85=E4=BC=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E6=8C=87?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- kni_comm.c | 67 ++- kni_comm.h | 59 +- kni_connect.c | 1481 ----------------------------------------------- kni_connect.h | 24 - kni_entry.c | 145 ++--- kni_entry.h | 304 +++++----- kni_ratelimit.c | 2 + kni_replace.c | 2 + 9 files changed, 295 insertions(+), 1793 deletions(-) delete mode 100644 kni_connect.c delete mode 100644 kni_connect.h diff --git a/Makefile b/Makefile index c9f6317..cbaf2ae 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = g++ CFLAGS = -g -Wall -fPIC -OBJECTS = kni_entry.o kni_comm.o kni_connect.o kni_ratelimit.o kni_replace.o +OBJECTS = kni_entry.o kni_comm.o kni_intercept.o kni_ratelimit.o kni_replace.o TARGET = kni.so #INCS = -I./inc @@ -22,7 +22,7 @@ $(TARGET):$(OBJECTS) kni_entry.o:kni_entry.c kni_comm.o:kni_comm.c -kni_connect.o:kni_connect.c +kni_intercept.o:kni_intercept.c kni_ratelimit.o:kni_ratelimit.c kni_replace.o:kni_replace.c diff --git a/kni_comm.c b/kni_comm.c index 375927b..4ad9efa 100644 --- a/kni_comm.c +++ b/kni_comm.c @@ -16,32 +16,45 @@ const char *g_kni_fs2_name[FS2_COLUMN_NUM] = { - "tcp/udp_entry", - "write_tun", - "read_tun", - "send_masio", - "whitelist_ip", - "whitelist_domain", - "http_protocol", - "ssl_protocol", - "droppkt_other", - "client_hello", - "ssl_sni", - "ipv6_option", - "not_in_htable", - "tcprepair_total", - "tcprepair_error", - "send_fds_succ", - "send_fds_error", - "pengding", - "close_timeout", - "close_fin", - "add_lqueue_succ", - "add_lqueue_err", - "get_lqueue_succ", - "get_lqueue_err", - "write_tun_succ", - "write_tun_err" + "TAPALL", + "UDP", + "IP", + "WHITE_IP", + "WHITE_DOMAIN", + "INTERCEPT", + "RATELIMIT", + "REPLACE", + "HTTP", + "SSL", + "NOT_PROC", + "TUN_WRITE", + "TUN_READ", + "SEND_MASION", + "CLIENT_HELLO", + "SSL_SNI(P)", + "D_IPV6_OPT", + "D_NOT_HTABLE", + "D_NOT_IPV4/6", + "D_NOT_IPV4/6", + "D_E_ADDHTABLE", + "D_OTHER", + "FD_TOTAL", + "FD_SOCKET_ERR", + "FD_ERROR", + "FD_JOINLQ_ERR", + "FD_GETLQ_ERR", + "FD_SEND_SUCC", + "FD_SEND_ERR", + "PKT_ADDLQ_SUC", + "PKT_ADDLQ_ERR", + "PKT_GETLQ_SUCC", + "PKT_GETLQ_ERR", + "PKT_WRITE_SUCC", + "PKT_WRITE_ERR", + "PENDING", + "CLOSE_TIMEOUT", + "CLOSE_FIN", + "REPLAY_WIN" }; @@ -423,7 +436,7 @@ int kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* ms } -char* kni_get_data(const struct streaminfo* pstream,int* datalen) +char* kni_get_payload(const struct streaminfo* pstream,int* datalen) { char* data=NULL; diff --git a/kni_comm.h b/kni_comm.h index 795f1cc..7e3e9d8 100644 --- a/kni_comm.h +++ b/kni_comm.h @@ -7,38 +7,51 @@ #endif -#define FS2_COLUMN_NUM 26 +#define FS2_COLUMN_NUM 39 #define FS2_APPNAME "KNI" enum kni_FS_COLUME { - FS2_COLUME_RECV=0, - FS2_COLUME_WRITE, - FS2_COLUME_READ, - FS2_COLUME_SEND, - FS2_COLUME_WITELIST_IP, - FS2_COLUME_WITELIST_DOMAIN, - FS2_COLUME_HTTP, - FS2_COLUME_SSL, - FS2_COLUME_DROPPKT, - FS2_COLUME_CLIENTHELLO, - FS2_COLUME_SNI, - FS2_COLUME_DROP_SAPP, - FS2_COLUME_DROP_TUN, - FS2_COLUME_TCPREPAIR_TOTAL, - FS2_COLUME_TCPREPAIR_ERROR, - FS2_COLUME_SENDTP_SUCC, - FS2_COLUME_SENDTP_ERROR, - FS2_COLUME_PENDING, - FS2_COLUME_CLOSE_TIMEOUT, - FS2_COLUME_CLOSE_FIN, + COLUME_TCPALL_ENTRY=0, + COLUME_UDP_ENTRY, + COLUME_IP_ENTRY, + COLUME_WITELIST_IP, + COLUME_WITELIST_DOMAIN, + COLUME_INTERCEPT, + COLUME_RATELIMIT, + COLUME_REPLACE, + COLUME_HTTP, + COLUME_SSL, + COLUME_TCP_NOT_HTTPSSL, + COLUME_TUN_WRITE, + COLUME_TUN_READ, + COLUME_SEND_PKT, + COLUME_CLIENTHELLO, + COLUME_SNI, + COLUME_DROP_IPV6OPT, + COLUME_DROP_NOIN_HTABLE, + COLUME_DROP_NOTIPV46_SAPP, + COLUME_DROP_NOTIPV46_TUN, + COLUME_DROP_ADDHTABLE_ERROR, + COLUME_DROPPKT_OTHER, + COLUME_TCPREPAIR_TOTAL, + COLUME_TCPREPAIR_SOCKET_ERR, + COLUME_TCPREPAIR_ERROR, + COLUME_TCPREPAIR_JOINLQ_ERR, + COLUME_TCPREPAIR_GETLQ_ERR, + COLUME_TCPREPAIR_SEND_SUCC, + COLUME_TCPREPAIR_SEND_ERR, COLUME_ADD_LQUEUE_SUCC, COLUME_ADD_LQUEUE_ERR, COLUME_GET_LQUEUE_SUCC, COLUME_GET_LQUEUE_ERR, COLUME_WRITE_TUN_SUCC, - COLUME_WRITE_TUN_ERR + COLUME_WRITE_TUN_ERR, + COLUME_PENDING, + COLUME_CLOSE_TIMEOUT, + COLUME_CLOSE_FIN, + COLUME_REPLAY_WINDOW }; @@ -66,7 +79,7 @@ int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr); int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen); int kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps); -char* kni_get_data(const struct streaminfo* pstream,int* datalen); +char* kni_get_payload(const struct streaminfo* pstream,int* datalen); int kni_filestate2_set(int thread_seq,int colum_index,int bytes,int pktnum); void* kni_filestat2(void* arg); diff --git a/kni_connect.c b/kni_connect.c deleted file mode 100644 index 0464aa5..0000000 --- a/kni_connect.c +++ /dev/null @@ -1,1481 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kni_connect.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_send_fds(int socket, int *fds, int n,int protocol) -{ - int flags=MSG_NOSIGNAL; - struct msghdr msg = {0}; - struct cmsghdr *cmsg; - char buf[CMSG_SPACE(n * sizeof(int))], dup[256]={0}; - memset(buf, 0, sizeof(buf)); -// struct iovec io = { .iov_base = &dup, .iov_len = sizeof(struct kni_tlv_info) }; - struct iovec io = { .iov_base = &dup, .iov_len = sizeof(dup) }; - - -//tlv info - struct kni_tlv_info tlv_info; - tlv_info.type=KNI_TLV_TYPE_PRO; - tlv_info.len=0x0001; - tlv_info.value=protocol; - memcpy(dup,&tlv_info,sizeof(struct kni_tlv_info)); -//end - - 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(n * sizeof(int)); - - memcpy ((int *) CMSG_DATA(cmsg), fds, n * sizeof (int)); - - // if (sendmsg (socket, &msg, 0) < 0) - 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_set_tlvinfo(char* buf,int buflen,struct kni_lqueue_datainfo 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_lqueue_datainfo datainfo) -{ - 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] = datainfo.client_fd; - fds[1] = datainfo.server_fd; - - - dup_len = kni_set_tlvinfo(dup,dup_len,datainfo); - - 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_sendfds_domain() -{ - int ret=0; - long datainfo_len = 0; - struct kni_lqueue_datainfo datainfo; - - - struct timespec start, end; - long elapse=0; - - - while(1) - { - clock_gettime(CLOCK_MONOTONIC, &start); - - memset(&datainfo,0,sizeof(datainfo)); - datainfo_len = sizeof(datainfo); - - - ret=MESA_lqueue_get_tail(g_kni_structinfo.lqueue_send_fds,&datainfo,&datainfo_len); - if(ret==MESA_QUEUE_RET_QEMPTY) - { - continue; - } - else if(ret<0) - { - MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_READTUN,"MESA_lqueue_try_get_tail() error!ret:%d\n",ret); - continue; - - } - - ret=kni_send_fds(g_kni_comminfo.fd_domain,datainfo); - if(ret<0) //check errno - { - kni_filestate2_set(0,FS2_COLUME_SENDTP_ERROR,0,2); - g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS; - - close(datainfo.client_fd); - close(datainfo.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 -1; - } - - kni_filestate2_set(0,FS2_COLUME_SENDTP_SUCC,0,2); - - close(datainfo.client_fd); - close(datainfo.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_connect_domain() -{ - while(1) - { - g_kni_comminfo.fd_domain=init_domain_fd(); - 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_process_domain(void* arg) -{ - while(1) - { - if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS) - { - kni_connect_domain(); - } - else - { - kni_sendfds_domain(); - } - } - - return 0; - -} - - - - -int init_domain_fd() -{ - - 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,"init_domain_fd():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,"init_domain_fd():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,"init_domain_fd","domain socket connect succ! "); - return i_fd; -} - -int init_kni_domain() -{ -#ifndef KNI_DEBUG_TCPREPAIR - - pthread_t pid_pro_domain; - - g_kni_comminfo.fd_domain=init_domain_fd(); - 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,"init_domain_fd()error"); - } - - pthread_create(&pid_pro_domain,NULL,kni_process_domain,NULL); - - return 0; - -#endif - -} - - -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 tun_read_data(int fd,char* recv_buf,int max_buflen) -{ - int recv_len=0; - - int ret=0; - int max_fd = 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; -} - - -int kni_add_lqueue(int addrtype,int thread_seq,char* send_buf,int send_buflen) -{ - int ret = 0; - struct kni_lqueue_writetun datainfo; - - datainfo.addr_type = addrtype; - datainfo.buflen = send_buflen; - datainfo.buf = (char*)malloc(send_buflen); - memcpy(datainfo.buf,send_buf,send_buflen); - - - ret=MESA_lqueue_join_head(g_kni_structinfo.lqueue_write_tun[thread_seq],(void*)&datainfo,sizeof(datainfo)); - if(ret <0) - { - 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 -1; - } - - kni_filestate2_set(thread_seq,COLUME_ADD_LQUEUE_SUCC,0,1); - - return 0; - -} - - - -char tun_write_data(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); - kni_filestate2_set(thread_seq,FS2_COLUME_DROPPKT,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_sendlenip6_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.ipv4_fd[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)); - } - - - kni_filestate2_set(thread_seq,FS2_COLUME_SEND,0,1); - - 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,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->wndpro_flag[index]=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) -{ -#ifdef KNI_DEBUG_TCPREPAIR - return 0; -#endif - - 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,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->wndpro_flag[index]=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->wndpro_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->wndpro_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) - { - if(g_kni_switch_info.sendpkt_mode == 1) - { - kni_sendpkt_routdir(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,FS2_COLUME_DROP_TUN,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) - { - if(g_kni_switch_info.sendpkt_mode == 1) - { - kni_sendpkt_routdir(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,FS2_COLUME_DROP_TUN,0,1); - } - - } - else - { - MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"kni_readdata,not ipv4 and not ipv6!"); - - } - - return 0; - -} - - - - - -/******************************************************************************************************************** -name: -function: -return: -*********************************************************************************************************************/ -void* kni_read_tun(void* arg) -{ - int ret = 0; - 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; - struct kni_lqueue_writetun datainfo; - long datainfo_len = sizeof(datainfo); - - while(1) - { - if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS) - { - sleep(KNI_USLEEP_TIME); - continue; - } -//write to run - datainfo_len = sizeof(datainfo); - - ret=MESA_lqueue_get_tail(g_kni_structinfo.lqueue_write_tun[thread_seq],&datainfo,&datainfo_len); - if(ret==MESA_QUEUE_RET_QEMPTY) - { - } - 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,KNI_MODULE_READTUN,"MESA_lqueue_try_get_tail() error!ret:%d,datalen:%d\n",ret,datainfo_len); - - } - else - { - kni_filestate2_set(thread_seq,COLUME_GET_LQUEUE_SUCC,0,1); - tun_write_data(g_kni_comminfo.fd_tun[thread_seq],datainfo.buf,datainfo.buflen,thread_seq); - - free(datainfo.buf); - datainfo.buf = NULL; - } - -//end - -//read from tun - clock_gettime(CLOCK_MONOTONIC, &start); - recv_len=0; - memset(recv_buf,0,KNI_MAX_BUFLEN); - - 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,FS2_COLUME_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_srcmss_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) -{ -#ifdef KNI_DEBUG_TCPREPAIR - return 0; -#endif - - kni_filestate2_set(pstream->threadnum,FS2_COLUME_TCPREPAIR_TOTAL,0,2); - - int ret=0; - struct kni_lqueue_datainfo datainfo; - - 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; - - - - 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 - { -//TODO - } - if ((fd_client < 0)||(fd_server<0)) - { - kni_filestate2_set(pstream->threadnum,FS2_COLUME_TCPREPAIR_ERROR,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,FS2_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,FS2_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); - - datainfo.client_fd = fd_client; - datainfo.server_fd = fd_server; - datainfo.protocol = pmeinfo->protocol; - datainfo.keyring = pmeinfo->keyring_id; - - - ret=MESA_lqueue_join_head(g_kni_structinfo.lqueue_send_fds,(void*)&datainfo,sizeof(datainfo)); - if(ret <0) - { - kni_filestate2_set(pstream->threadnum,FS2_COLUME_TCPREPAIR_ERROR,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); - } - - - pmeinfo->client_fd = fd_client; - pmeinfo->server_fd = fd_server; - - return 0; - -} - - - - - - diff --git a/kni_connect.h b/kni_connect.h deleted file mode 100644 index 044fbb0..0000000 --- a/kni_connect.h +++ /dev/null @@ -1,24 +0,0 @@ -#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(int fd,char* send_buf,int send_buflen,int thread_seq); - - -int init_domain_fd(); -int init_kni_domain(); -int init_kni_tun(); - -void* kni_read_tun(void* arg); -int kni_add_lqueue(int addrtype,int thread_seq,char* send_buf,int send_buflen); - -int tcp_repair_process(const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo,int protocol); - - - -#endif - diff --git a/kni_entry.c b/kni_entry.c index 93d2872..ce3c66f 100644 --- a/kni_entry.c +++ b/kni_entry.c @@ -10,7 +10,7 @@ -int g_kni_version_VERSION_20181123_test; +int g_kni_version_VERSION_20181125_addlog; struct kni_var_comm g_kni_comminfo; struct kni_var_struct g_kni_structinfo; @@ -118,6 +118,7 @@ int kni_scan_ip(struct ipaddr* addr,int thread_seq,int protocol,struct kni_pme_i int kni_htable_add(const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo) { + int ret = 0; int iprevers=0; struct stream_tuple4_v4 ipv4_addr; struct stream_tuple4_v6 ipv6_addr; @@ -126,7 +127,7 @@ int kni_htable_add(const struct streaminfo* pstream,const void* a_packet,struct memset(datainfo,0,sizeof(struct kni_htable_datainfo)); -//send pkt info +//send pkt info by self if(iprevers==0) { datainfo->route_dir=pstream->routedir; @@ -149,19 +150,30 @@ int kni_htable_add(const struct streaminfo* pstream,const void* a_packet,struct } //send wnd_pro_reply info - memcpy(&(datainfo->tcpopt_info),&(pmeinfo->tcpopt_info),KNI_DIR_DOUBLE*sizeof(struct kni_tcpopt_info)); +// memcpy(&(datainfo->tcpopt_info),&(pmeinfo->tcpopt_info),KNI_DIR_DOUBLE*sizeof(struct kni_tcpopt_info)); memcpy(&(datainfo->lastpkt_info),&(pmeinfo->lastpkt_info),KNI_DIR_DOUBLE*sizeof(struct kni_wndpro_reply_info)); if(pstream->addr.addrtype == ADDR_TYPE_IPV4) { iprevers=kni_get_ipaddr_v4((void*)a_packet,&ipv4_addr); - MESA_htable_add(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),(void*)datainfo); + ret = MESA_htable_add(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),(void*)datainfo); + if(ret < 0) + { + kni_log_debug(RLOG_LV_INFO,(char*)"kni_htable_add",a_packet,"IPv4 MESA_htable_add() error,ret:%d",ret); + return -1; + } } else { iprevers=kni_get_ipaddr_v6((void*)a_packet,&ipv6_addr); - MESA_htable_add(g_kni_structinfo.htable_to_tun_v6,(unsigned char*)&ipv6_addr,sizeof(struct stream_tuple4_v6),(void*)datainfo); + ret = MESA_htable_add(g_kni_structinfo.htable_to_tun_v6,(unsigned char*)&ipv6_addr,sizeof(struct stream_tuple4_v6),(void*)datainfo); + if(ret < 0) + { + kni_log_debug(RLOG_LV_INFO,(char*)"kni_htable_add",a_packet,"IPv6 MESA_htable_add() error,ret:%d",ret); + return -1; + } + } @@ -237,7 +249,7 @@ int kni_judge_ssl(int thread_seq,char* tcp_data,int tcp_datalen,char* sni,int* s ssl_body_len+=1; *clienthello_flag = 1; - kni_filestate2_set(thread_seq,FS2_COLUME_CLIENTHELLO,0,1); + kni_filestate2_set(thread_seq,COLUME_CLIENTHELLO,0,1); // memcpy(&len_in_body,&ssl_body[ssl_body_len],3); @@ -291,7 +303,7 @@ int kni_judge_ssl(int thread_seq,char* tcp_data,int tcp_datalen,char* sni,int* s if(type_in_extension==SSL_EXTENSION_TYPE_SNI) { *sni_flag = 1; - kni_filestate2_set(thread_seq,FS2_COLUME_SNI,0,1); + kni_filestate2_set(thread_seq,COLUME_SNI,0,1); if(len_in_extension>KNI_SNI_MAXLEN) { @@ -347,12 +359,12 @@ int kni_protocol_identify(const struct streaminfo* pstream,const void* a_packet, if(kni_judge_http(pstream,domain,domain_len)==1) { - kni_filestate2_set(pstream->threadnum,FS2_COLUME_HTTP,0,1); + kni_filestate2_set(pstream->threadnum,COLUME_HTTP,0,1); return KNI_FLAG_HTTP; } else if(kni_judge_ssl(pstream->threadnum,tcp_data,tcp_datalen,domain,domain_len,&clienthello_flag,&sni_flag)==KNI_FLAG_SSL) { - kni_filestate2_set(pstream->threadnum,FS2_COLUME_SSL,0,1); + kni_filestate2_set(pstream->threadnum,COLUME_SSL,0,1); return KNI_FLAG_SSL; } //modify by liuyang 20180911 for client_hello but no sni @@ -423,13 +435,14 @@ char kni_first_tcpdata(const struct streaminfo* pstream,const void* a_packet,str switch(pmeinfo->action) { case KNI_ACTION_WHITELIST: - kni_filestate2_set(pstream->threadnum,FS2_COLUME_WITELIST_DOMAIN,0,1); + kni_filestate2_set(pstream->threadnum,COLUME_WITELIST_DOMAIN,0,1); kni_log_info((char*)KNI_MODULE_INFO,&(pstream->addr),pmeinfo->protocol,domain,(char*)"WHITE_LIST_DOMAIN",(char*)"BYPASS",pmeinfo); pmeinfo->protocol=KNI_FLAG_NOTPROC; return ret; case KNI_ACTION_RATELIMIT: + kni_filestate2_set(pstream->threadnum,COLUME_RATELIMIT,0,1); kni_log_info((char*)KNI_MODULE_INFO,&(pstream->addr),pstream->type,NULL,(char*)"RATELIMITE",(char*)"RATELIMITE",pmeinfo); ret = kni_process_ratelimit(pstream->threadnum,a_packet,pmeinfo); return ret; @@ -451,8 +464,13 @@ char kni_first_tcpdata(const struct streaminfo* pstream,const void* a_packet,str } -// kni_get_keyring(pmeinfo); - kni_htable_add(pstream,a_packet,pmeinfo); + kni_filestate2_set(pstream->threadnum,COLUME_INTERCEPT,0,1); + + if(kni_htable_add(pstream,a_packet,pmeinfo) < 0) + { + kni_filestate2_set(pstream->threadnum,COLUME_DROP_ADDHTABLE_ERROR,0,1); + return ret; + } clock_gettime(CLOCK_MONOTONIC, &start); @@ -467,7 +485,6 @@ char kni_first_tcpdata(const struct streaminfo* pstream,const void* a_packet,str MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,"tcp_repair_process","tcp_repair_process() error!"); return ret; } - clock_gettime(CLOCK_MONOTONIC, &end); @@ -481,6 +498,7 @@ char kni_first_tcpdata(const struct streaminfo* pstream,const void* a_packet,str } else { + kni_filestate2_set(pstream->threadnum,COLUME_TCP_NOT_HTTPSSL,0,1); kni_log_info((char*)KNI_MODULE_INFO,&(pstream->addr),pmeinfo->protocol,NULL,(char*)"NOT_HTTP_SSL",(char*)"BYPASS",pmeinfo); } @@ -504,7 +522,7 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p struct kni_ipv6_hdr* ipv6_hdr = NULL; struct kni_tcp_hdr* tcphdr=NULL; - data=kni_get_data(pstream,&datalen); + data=kni_get_payload(pstream,&datalen); if(pstream->addr.addrtype==ADDR_TYPE_IPV4) { @@ -522,6 +540,7 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p } else { + kni_filestate2_set(thread_seq,COLUME_DROP_NOTIPV46_SAPP,0,1); return ret; } @@ -530,7 +549,7 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p if(pmeinfo->action==KNI_ACTION_WHITELIST) { kni_log_info((char*)KNI_MODULE_INFO,&(pstream->addr),0,NULL,(char*)"WHITE_LIST_IP",(char*)"BYPASS",pmeinfo); - kni_filestate2_set(thread_seq,FS2_COLUME_WITELIST_IP,0,1); + kni_filestate2_set(thread_seq,COLUME_WITELIST_IP,0,1); return ret; } @@ -589,7 +608,7 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei struct kni_ipv6_hdr* ipv6_hdr = NULL; struct kni_tcp_hdr* tcphdr=NULL; - data=kni_get_data(pstream,&datalen); + data=kni_get_payload(pstream,&datalen); if(pstream->addr.addrtype==ADDR_TYPE_IPV4) { @@ -607,6 +626,7 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei } else { + kni_filestate2_set(thread_seq,COLUME_DROP_NOTIPV46_SAPP,0,1); return ret; } @@ -633,6 +653,7 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei if((pmeinfo->action == KNI_ACTION_MONITOR) && ((pmeinfo->protocol==KNI_FLAG_HTTP)||(pmeinfo->protocol==KNI_FLAG_SSL))) { + kni_filestate2_set(pstream->threadnum,COLUME_INTERCEPT,0,1); kni_add_lqueue(ADDR_TYPE_IPV4,thread_seq,(char*)a_packet,iplen); // ret=tun_write_data(g_kni_comminfo.fd_tun[thread_seq],(char*)a_packet,iplen,(struct streaminfo*)pstream,thread_seq); } @@ -701,7 +722,7 @@ extern "C" char kni_udp_entry(const struct streaminfo* pstream,void** pme,int th } - kni_filestate2_set(thread_seq,FS2_COLUME_RECV,0,1); + kni_filestate2_set(thread_seq,COLUME_UDP_ENTRY,0,1); switch(pstream->opstate) { @@ -755,18 +776,18 @@ extern "C" char kni_tcpall_entry(const struct streaminfo* pstream,void** pme,int if((a_packet != NULL) && (ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP)) { - kni_filestate2_set(thread_seq,FS2_COLUME_DROP_SAPP,0,1); + kni_filestate2_set(thread_seq,COLUME_DROP_IPV6OPT,0,1); return ret; } } - kni_filestate2_set(thread_seq,FS2_COLUME_RECV,0,1); + kni_filestate2_set(thread_seq,COLUME_TCPALL_ENTRY,0,1); switch(pstream->pktstate) { case OP_STATE_PENDING: - kni_filestate2_set(thread_seq,FS2_COLUME_PENDING,0,1); + kni_filestate2_set(thread_seq,COLUME_PENDING,0,1); kni_init_pmeinfo(pme); ret=kni_pending_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,a_packet,PROTO_TYPE_TCP); break; @@ -778,11 +799,11 @@ extern "C" char kni_tcpall_entry(const struct streaminfo* pstream,void** pme,int case OP_STATE_CLOSE: if(a_packet == NULL) { - kni_filestate2_set(thread_seq,FS2_COLUME_CLOSE_TIMEOUT,0,1); + kni_filestate2_set(thread_seq,COLUME_CLOSE_TIMEOUT,0,1); } else { - kni_filestate2_set(thread_seq,FS2_COLUME_CLOSE_FIN,0,1); + kni_filestate2_set(thread_seq,COLUME_CLOSE_FIN,0,1); } ret=kni_close_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,a_packet,PROTO_TYPE_TCP); @@ -832,6 +853,8 @@ extern "C" char kni_ipv4_entry(const struct streaminfo *pstream,unsigned char ro return APP_STATE_DROPME; } + kni_filestate2_set(thread_seq,COLUME_IP_ENTRY,0,1); + char ret = APP_STATE_GIVEME; scan_status_t mid = NULL; @@ -889,6 +912,8 @@ extern "C" char kni_ipv6_entry(const struct streaminfo *pstream,unsigned char ro { return ret; } + + kni_filestate2_set(thread_seq,COLUME_IP_ENTRY,0,1); addr.addrtype = ADDR_TYPE_IPV6; @@ -1015,7 +1040,6 @@ int init_profile_info() 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_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"tun_name",g_kni_comminfo.tun_name,KNI_CONF_MAXLEN,"tun0"); 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); @@ -1150,7 +1174,7 @@ int init_kni_dyn_maat_info() } -int init_kni_maat_info() +int init_kni_static_maat_info() { int ret = 0; @@ -1261,19 +1285,19 @@ int init_kni_sendpkt() kni_read_cardname(); - g_kni_comminfo.ipv4_fd=(int*)malloc(g_kni_comminfo.thread_num*sizeof(int)); + g_kni_comminfo.fd_sendpkt=(int*)malloc(g_kni_comminfo.thread_num*sizeof(int)); for(i=0;iratelimit_info); diff --git a/kni_replace.c b/kni_replace.c index 1af5fa5..f0a5fbf 100644 --- a/kni_replace.c +++ b/kni_replace.c @@ -134,6 +134,8 @@ char kni_process_replace(unsigned char dir,int thread_seq,const void* a_packet,s } + kni_filestate2_set(thread_seq,COLUME_REPLACE,0,1); + // char ret = APP_STATE_DROPPKT | APP_STATE_DROPME; char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;