2018-08-22 14:50:00 +08:00
# 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 ;
}
2018-09-19 10:26:39 +08:00
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 ;
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 , htonl ( 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 ) ;
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 ;
}
2018-08-22 14:50:00 +08:00
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 ) ;
2018-09-19 10:26:39 +08:00
kni_log_debug ( RLOG_LV_DEBUG , ( char * ) " win_update " , ( struct ip * ) a_packet , ( char * ) " recv tcp_repair windows update,and replay " ) ;
2018-08-22 14:50:00 +08:00
free ( sendbuf ) ;
sendbuf = NULL ;
datainfo - > wndpro_flag [ index ] = 1 ;
return 1 ;
}
2018-09-19 10:26:39 +08:00
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
{
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 ;
}
2018-08-22 14:50:00 +08:00
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
{
2018-09-18 17:13:28 +08:00
args - > routdir = MESA_dir_reverse ( datainfo - > route_dir ) ;
2018-08-22 14:50:00 +08:00
}
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
{
2018-09-19 10:26:39 +08:00
kni_log_debug ( RLOG_LV_INFO , " htable_cb " , ( struct ip * ) args - > a_packet , ( char * ) " read_tun,data=NULL,sip not 192.168.66.101 " ) ;
2018-08-22 14:50:00 +08:00
}
# endif
return result ;
}
2018-09-18 17:13:28 +08:00
int kni_process_readdata ( int thread_seq , int sendpkt_threadid , int buflen , char * buf )
2018-08-22 14:50:00 +08:00
{
int iprever_flag = 0 ;
long result = 0 ;
2018-09-19 10:26:39 +08:00
struct ip * ipv4_hdr = ( struct ip * ) buf ;
struct kni_ipv6_hdr * ipv6_hdr = ( struct kni_ipv6_hdr * ) buf ;
2018-08-22 14:50:00 +08:00
struct stream_tuple4_v4 ipv4_addr ;
2018-09-19 10:26:39 +08:00
struct stream_tuple4_v6 ipv6_addr ;
2018-08-22 14:50:00 +08:00
struct args_read_tun args ;
2018-09-19 10:26:39 +08:00
if ( ipv4_hdr - > ip_v = = 4 )
2018-08-22 14:50:00 +08:00
{
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 )
{
2018-09-18 17:13:28 +08:00
// kni_sendpkt_routdir(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
2018-09-19 10:26:39 +08:00
MESA_sendpacket_iplayer_options ( thread_seq , buf , buflen , args . routdir , NULL , 0 ) ;
2018-09-18 17:13:28 +08:00
2018-08-22 14:50:00 +08:00
}
}
2018-09-19 10:26:39 +08:00
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_sendpkt_routdir(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
MESA_sendpacket_iplayer_options ( thread_seq , buf , buflen , args . routdir , NULL , 0 ) ;
}
}
2018-08-22 14:50:00 +08:00
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 } ;
2018-09-18 17:13:28 +08:00
int sendpkt_threadid = 0 ;
int sendpkt_threadid_len = sizeof ( int ) ;
sapp_get_platform_opt ( SPO_INDEPENDENT_THREAD_ID , & sendpkt_threadid , & sendpkt_threadid_len ) ;
2018-08-22 14:50:00 +08:00
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 ) ;
2018-09-18 17:13:28 +08:00
kni_process_readdata ( thread_seq , sendpkt_threadid , recv_len , recv_buf ) ;
2018-08-22 14:50:00 +08:00
}
}
return 0 ;
}