703 lines
16 KiB
C
703 lines
16 KiB
C
|
|
#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 "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_sendfds_domain()
|
||
|
|
{
|
||
|
|
int ret=0;
|
||
|
|
long fds_len=KNI_FDS_NUM*sizeof(int);
|
||
|
|
int fds[KNI_FDS_NUM]={0};
|
||
|
|
|
||
|
|
while(1)
|
||
|
|
{
|
||
|
|
memset(fds,0,KNI_FDS_NUM*sizeof(int));
|
||
|
|
fds_len=KNI_FDS_NUM*sizeof(int);
|
||
|
|
|
||
|
|
ret=MESA_lqueue_get_tail(g_kni_structinfo.lqueue_for_domain,fds,&fds_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,fds,2,fds[KNI_FDS_INDEX_PROTOCOL]);
|
||
|
|
if(ret<0) //check errno
|
||
|
|
{
|
||
|
|
g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
close(fds[KNI_FDS_INDEX_CLIENT]);
|
||
|
|
close(fds[KNI_FDS_INDEX_SERVER]);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
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)
|
||
|
|
{
|
||
|
|
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(clonedev, 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;
|
||
|
|
|
||
|
|
FD_ZERO(&alive_readfd);
|
||
|
|
FD_SET(fd, &alive_readfd);
|
||
|
|
max_fd = fd;
|
||
|
|
|
||
|
|
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(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;
|
||
|
|
|
||
|
|
succ_sendlen = write(fd, send_buf,send_buflen);
|
||
|
|
if((succ_sendlen<0)&&(pstream!=NULL))
|
||
|
|
{
|
||
|
|
kni_filestate2_set(thread_seq,FS2_COLUME_DROPPKT,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)
|
||
|
|
{
|
||
|
|
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,FS2_COLUME_WRITE,0,1);
|
||
|
|
|
||
|
|
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;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int init_kni_tun()
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
|
||
|
|
g_kni_comminfo.thread_num=g_iThreadNum;
|
||
|
|
if(g_kni_comminfo.thread_num<=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.thread_num*sizeof(int));
|
||
|
|
memset(g_kni_comminfo.fd_tun,0,g_kni_comminfo.thread_num*sizeof(int));
|
||
|
|
|
||
|
|
ret=tun_alloc_mq(g_kni_comminfo.tun_name,g_kni_comminfo.thread_num,g_kni_comminfo.fd_tun);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int kni_sendpkt_routdir(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_routdir","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;
|
||
|
|
|
||
|
|
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.ipv4_fd[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.ipv4_fd[thread_seq],SIOCGIFHWADDR,&ifr)==-1)
|
||
|
|
{
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
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(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;
|
||
|
|
// unsigned short ipid=random()%65535;
|
||
|
|
|
||
|
|
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_iphdr->ip_id=ipid;
|
||
|
|
// snd_iphdr->ip_id=htons(datainfo->lastpkt_info[index].ipid+1);
|
||
|
|
// snd_iphdr->ip_ttl=datainfo->lastpkt_info[index].ttl;
|
||
|
|
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
if(iprever_flag==0)
|
||
|
|
{
|
||
|
|
snd_iphdr->ip_id=ipid;
|
||
|
|
snd_tcphdr->window=htons((win>>win_scale)+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);
|
||
|
|
|
||
|
|
kni_log_debug_v4(RLOG_LV_DEBUG,(char*)"win_update",(struct ip*)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_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
|
||
|
|
{
|
||
|
|
// args->routdir=MESA_dir_reverse(datainfo->route_dir);
|
||
|
|
args->routdir=1-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_v4(RLOG_LV_INFO,"htable_cb",(struct ip*)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 buflen,char* buf)
|
||
|
|
{
|
||
|
|
int iprever_flag=0;
|
||
|
|
long result=0;
|
||
|
|
|
||
|
|
struct ip* iphdr=(struct ip*)buf;
|
||
|
|
struct stream_tuple4_v4 ipv4_addr;
|
||
|
|
|
||
|
|
struct args_read_tun args;
|
||
|
|
|
||
|
|
if(iphdr->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_sendpkt_eth(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
|
||
|
|
kni_sendpkt_routdir(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************************************************************
|
||
|
|
name:
|
||
|
|
function:
|
||
|
|
return:
|
||
|
|
*********************************************************************************************************************/
|
||
|
|
void* kni_read_tun(void* arg)
|
||
|
|
{
|
||
|
|
int thread_seq=*(int*)arg;
|
||
|
|
|
||
|
|
int recv_len=0;
|
||
|
|
char recv_buf[KNI_MAX_BUFLEN] = {0};
|
||
|
|
|
||
|
|
|
||
|
|
while(1)
|
||
|
|
{
|
||
|
|
if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS)
|
||
|
|
{
|
||
|
|
sleep(KNI_USLEEP_TIME);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
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)
|
||
|
|
{
|
||
|
|
kni_filestate2_set(thread_seq,FS2_COLUME_READ,0,1);
|
||
|
|
kni_process_readdata(thread_seq,recv_len,recv_buf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|