#include <xcopy.h>
#include <tcpcopy.h>
static hash_table *sessions_table;
static hash_table *tf_port_table;
#if (TCPCOPY_MYSQL_BASIC)
static hash_table *mysql_table;
#endif
#if (TCPCOPY_MYSQL_ADVANCED)
static hash_table *existed_sessions;
static hash_table *fir_auth_pack_table;
static hash_table *sec_auth_pack_table;
#endif
/* total sessions deleted */
static uint64_t leave_cnt = 0;
/* total obsolete sessions */
static uint64_t obs_cnt = 0;
/* total client syn packets */
static uint64_t clt_syn_cnt = 0;
#if (TCPCOPY_MYSQL_ADVANCED)
static uint64_t clt_dropped_cnt = 0;
#endif
/* total client content packets */
static uint64_t clt_cont_cnt = 0;
/* total client packets */
static uint64_t clt_packs_cnt = 0;
/* total client packets sent to backend */
static uint64_t packs_sent_cnt = 0;
/* total client content packets sent to backend */
static uint64_t con_packs_sent_cnt = 0;
/* total response packets */
static uint64_t resp_cnt = 0;
/* total response content packets */
static uint64_t resp_cont_cnt = 0;
/* total connections successfully cheated */
static uint64_t conn_cnt = 0;
/* total successful retransmission */
static uint64_t retrans_succ_cnt = 0;
/* total retransmission */
static uint64_t retrans_cnt = 0;
/* total reconnections for backend */
static uint64_t recon_for_closed_cnt = 0;
/* total reconnections for halfway interception */
static uint64_t recon_for_no_syn_cnt = 0;
/* start time for excuting the process function */
static time_t start_p_time = 0;
#if (TCPCOPY_MYSQL_BASIC)
/* global sequence omission */
static uint32_t g_seq_omit = 0;
/* the global first authentication user packet */
static tc_ip_header_t *fir_auth_u_p = NULL;
#endif
static bool
check_session_over(session_t *s)
{
if (s->sm.reset) {
return true;
}
if (s->sm.sess_over) {
return true;
}
return false;
}
static bool
trim_packet(session_t *s, tc_ip_header_t *ip_header,
tc_tcp_header_t *tcp_header, uint32_t diff)
{
uint16_t size_ip, size_tcp, tot_len, cont_len;
unsigned char *payload;
size_ip = ip_header->ihl << 2;
tot_len = ntohs(ip_header->tot_len);
size_ip = ip_header->ihl << 2;
size_tcp = tcp_header->doff << 2;
cont_len = tot_len - size_tcp - size_ip;
if (cont_len <= diff) {
return false;
}
ip_header->tot_len = htons(tot_len - diff);
tcp_header->seq = htonl(s->vir_next_seq);
payload = (unsigned char *) ((char *) tcp_header + size_tcp);
memmove(payload, payload + diff, cont_len - diff);
tc_log_debug1(LOG_DEBUG, 0, "trim packet:%u", s->src_h_port);
return true;
}
/*
* it is called by fast retransmit
*/
static void
wrap_retransmit_ip_packet(session_t *s, unsigned char *data)
{
int ret, tcp_opt_len;
uint16_t size_ip, tot_len, cont_len;
unsigned char *payload, *tcp_opt;
tc_ip_header_t *ip_header;
tc_tcp_header_t *tcp_header;
if (data == NULL) {
tc_log_info(LOG_ERR, 0, "error ip data is null");
return;
}
ip_header = (tc_ip_header_t *) data;
size_ip = ip_header->ihl << 2;
tcp_header = (tc_tcp_header_t *) (data + size_ip);
/* set the destination ip and port */
ip_header->daddr = s->dst_addr;
tcp_header->dest = s->dst_port;
tot_len = ntohs(ip_header->tot_len);
cont_len = TCP_PAYLOAD_LENGTH(ip_header, tcp_header);
if (tcp_header->doff > TCP_HEADER_DOFF_MIN_VALUE) {
tcp_opt_len = (tcp_header->doff - TCP_HEADER_DOFF_MIN_VALUE) << 2;
if (cont_len > 0) {
tcp_opt = (unsigned char *) ((char *) tcp_header
+ (TCP_HEADER_DOFF_MIN_VALUE << 2));
payload = (unsigned char *) (tcp_opt + tcp_opt_len);
/* overide tcp options just for fast retransmit */
memmove(tcp_opt, payload, cont_len);
}
tot_len = tot_len - tcp_opt_len;
ip_header->tot_len = htons(tot_len);
tcp_header->doff = TCP_HEADER_DOFF_MIN_VALUE;
}
if (cont_len > 0) {
s->sm.vir_new_retransmit = 1;
s->resp_last_same_ack_num = 0;
retrans_cnt++;
}
/* It should be set to zero for tcp checksum */
tcp_header->check = 0;
tcp_header->check = tcpcsum((unsigned char *) ip_header,
(unsigned short *) tcp_header, (int) (tot_len - size_ip));
tc_log_trace(LOG_NOTICE, 0, TO_BAKEND_FLAG, ip_header, tcp_header);
ret = tc_raw_socket_send(tc_raw_socket_out, ip_header, tot_len,
ip_header->daddr);
if (ret == TC_ERROR) {
tc_log_trace(LOG_WARN, 0, TO_BAKEND_FLAG, ip_header, tcp_header);
tc_log_info(LOG_ERR, 0, "send to back error,tot_len is:%d,cont_len:%d",
tot_len,cont_len);
}
}
/*
* wrap sending ip packet function
*/
static void
wrap_send_ip_packet(session_t *s, unsigned char *data, bool client)
{
int ret;
uint16_t size_ip, tot_len, cont_len;
p_link_node ln;
tc_ip_header_t *ip_header;
tc_tcp_header_t *tcp_header;
if (data == NULL) {
tc_log_info(LOG_ERR, 0, "error ip data is null");
return;
}
ip_header = (tc_ip_header_t *) data;
size_ip = ip_header->ihl << 2;
tcp_header = (tc_tcp_header_t *) (data + size_ip);
if (client) {
s->req_last_ack_sent_seq = ntohl(tcp_header->ack_seq);
s->sm.req_valid_last_ack_sent = 1;
}
/* set the destination ip and port */
ip_header->daddr = s->dst_addr;
tcp_header->dest = s->dst_port;
s->vir_next_seq = ntohl(tcp_header->seq);
/* add virtual next seq when meeting syn or fin packet */
if (tcp_header->syn || tcp_header->fin) {
if (tcp_header->syn) {
s->sm.req_valid_last_ack_sent = 0;
s->sm.status = SYN_SENT;
s->req_last_syn_seq = tcp_header->seq;
} else {
s->sm.fin_add_seq = 1;
}
s->vir_next_seq = s->vir_next_seq + 1;
}
if (tcp_header->ack) {
tcp_header->ack_seq = s->vir_ack_seq;
#if (TCPCOPY_PAPER)
s->resp_unack_time = 0;
#endif
}
tot_len = ntohs(ip_header->tot_len);
cont_len = TCP_PAYLOAD_LENGTH(ip_header, tcp_header);
if (cont_len > 0) {
s->sm.status = SEND_REQ;
s->req_last_send_cont_time = tc_time();
s->req_last_cont_sent_seq = htonl(tcp_header->seq);
s->vir_next_seq = s->vir_next_seq + cont_len;
if (s->sm.unack_pack_omit_save_flag) {
/*It must be a retransmission packet */
s->sm.vir_new_retransmit = 1;
} else {
con_packs_sent_cnt++;
}
}
/* It should be set to zero for tcp checksum */
tcp_header->check = 0;
tcp_header->check = tcpcsum((unsigned char *) ip_header,
(unsigned short *) tcp_header, (int) (tot_len - size_ip));
tc_log_debug_trace(LOG_DEBUG, 0, TO_BAKEND_FLAG, ip_header, tcp_header);
packs_sent_cnt++;
s->req_ip_id = ntohs(ip_header->id);
if (!s->sm.unack_pack_omit_save_flag) {
if (cont_len > 0) {
ln = link_node_malloc(copy_ip_packet(ip_header));
#if (!TCPCOPY_PAPER)
link_list_append(s->unack_packets, ln);
#else
ln->key = ntohl(tcp_header->seq);
link_list_append_by_order(s->unack_packets, ln);
#endif
}
} else {
s->sm.unack_pack_omit_save_flag = 0;
}
ret = tc_raw_socket_send(tc_raw_socket_out, ip_header, tot_len,
ip_header->daddr);
if (ret == TC_ERROR) {
tc_log_trace(LOG_WARN, 0, TO_BAKEND_FLAG, ip_header, tcp_header);
tc_log_info(LOG_ERR, 0, "send to back error,tot_len is:%d,cont_len:%d",
tot_len, cont_len);
}
}
static void
fill_pro_common_header(tc_ip_header_t *ip_header, tc_tcp_header_t *tcp_header)
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
















收起资源包目录
































































































共 86 条
- 1

eggeryudan
- 粉丝: 0
- 资源: 4
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


会员权益专享
安全验证
文档复制为VIP权益,开通VIP直接复制

- 1
- 2
前往页