修正解密流量转发中重建TCP流部分序列号错误的问题。
This commit is contained in:
@@ -6,16 +6,14 @@
|
||||
|
||||
struct traffic_mirror_rebuild
|
||||
{
|
||||
struct tfe_stream_addr * addr;
|
||||
struct tfe_stream_addr * c_s_addr;
|
||||
struct tfe_stream_addr * s_c_addr;
|
||||
|
||||
struct profile_table_ex_data * target;
|
||||
struct traffic_mirror_ethdev * ethdev;
|
||||
|
||||
uint32_t c_seq;
|
||||
uint32_t s_seq;
|
||||
uint32_t c_ipid;
|
||||
uint32_t s_ipid;
|
||||
uint8_t c_ttl;
|
||||
uint8_t s_ttl;
|
||||
};
|
||||
|
||||
/* The definition of vlan_hdr and tcp_hdr is from DPDK 17.05 */
|
||||
@@ -56,7 +54,7 @@ static int tcp_header_construct(unsigned char *buf, unsigned short sp,
|
||||
tcp_hdr->dst_port = dp;
|
||||
tcp_hdr->sent_seq = htonl(seq);
|
||||
tcp_hdr->recv_ack = htonl(ack);
|
||||
tcp_hdr->data_off = 5;
|
||||
tcp_hdr->data_off = 0x50;
|
||||
tcp_hdr->tcp_flags = flags;
|
||||
tcp_hdr->rx_win = htons(win);
|
||||
tcp_hdr->cksum = 0;
|
||||
@@ -188,24 +186,25 @@ static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, stru
|
||||
unsigned int seq, unsigned int ack, char flags)
|
||||
{
|
||||
char pkt[ETHER_MAX_LEN];
|
||||
unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct vlan_hdr) + sizeof(struct iphdr) + sizeof(struct tcphdr);
|
||||
unsigned l3_l4_header_len = 0;
|
||||
|
||||
unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct vlan_hdr) +
|
||||
sizeof(struct iphdr) + sizeof(struct tcphdr);
|
||||
|
||||
unsigned header_len = 0;
|
||||
|
||||
header_len = tcp_header_construct_by_stream_addr(addr,
|
||||
(unsigned char *)pkt + sz_pkt_prepend, seq, ack, flags, 0xffff, 0);
|
||||
assert(sizeof(pkt) - sz_pkt_prepend >= payload_len);
|
||||
memcpy(pkt + sz_pkt_prepend, payload, payload_len);
|
||||
|
||||
sz_pkt_prepend -= header_len;
|
||||
l3_l4_header_len += header_len;
|
||||
sz_pkt_prepend -= sizeof(struct tcp_hdr);
|
||||
header_len += tcp_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
||||
seq, ack, flags, 0xffff, 0);
|
||||
|
||||
header_len = ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
||||
sizeof(struct tcphdr) + payload_len, 0, 0x1000, 0, 128, IPPROTO_TCP);
|
||||
|
||||
sz_pkt_prepend -= header_len;
|
||||
l3_l4_header_len += header_len;
|
||||
sz_pkt_prepend -= sizeof(struct iphdr);
|
||||
header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
||||
header_len + payload_len, 0, 0x1000, 0, 128, IPPROTO_TCP);
|
||||
|
||||
l2_send_to_target_group(ethdev, t_group, (unsigned char *)pkt, sz_pkt_prepend,
|
||||
l3_l4_header_len + payload_len, ETHERTYPE_IP);
|
||||
header_len + payload_len, ETHERTYPE_IP);
|
||||
}
|
||||
|
||||
static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev,
|
||||
@@ -215,16 +214,21 @@ static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traff
|
||||
unsigned int payload_offset = 0;
|
||||
unsigned mss = ethdev->mtu - (sizeof(struct iphdr) + sizeof(struct tcphdr));
|
||||
|
||||
while(payload_offset <= payload_len)
|
||||
/* Handshake or farewall */
|
||||
if (payload == NULL || payload_len == 0)
|
||||
{
|
||||
unsigned int payload_sz_seg = MIN(payload_offset, mss);
|
||||
tcp_segment_send_to_target_group(addr, ethdev, t_group, NULL, 0, seq, ack, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
while(payload_offset < payload_len)
|
||||
{
|
||||
unsigned int payload_sz_seg = MIN(payload_len - payload_offset, mss);
|
||||
const char * payload_ptr_seg = payload + payload_offset;
|
||||
|
||||
tcp_segment_send_to_target_group(addr, ethdev, t_group, payload_ptr_seg, payload_sz_seg, seq, ack, flags);
|
||||
seq += payload_sz_seg;
|
||||
payload_offset += payload_sz_seg;
|
||||
|
||||
if (payload_sz_seg == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +236,8 @@ struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_
|
||||
struct profile_table_ex_data * target, struct traffic_mirror_ethdev * ethdev)
|
||||
{
|
||||
struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1);
|
||||
instance->addr = addr;
|
||||
instance->c_s_addr = addr;
|
||||
instance->s_c_addr = tfe_stream_addr_reverse(addr);
|
||||
instance->target = target;
|
||||
instance->ethdev = ethdev;
|
||||
|
||||
@@ -240,27 +245,24 @@ struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_
|
||||
* TODO: use the fast random algorithm like Linux TCP/IP stack */
|
||||
instance->c_seq = random();
|
||||
instance->s_seq = random();
|
||||
instance->c_ipid = random();
|
||||
instance->s_ipid = random();
|
||||
instance->s_ttl = 128;
|
||||
instance->c_ttl = 64;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance)
|
||||
{
|
||||
tfe_stream_addr_free(instance->s_c_addr);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance)
|
||||
{
|
||||
tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target,
|
||||
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->c_seq, 0, TCP_SYN_FLAG);
|
||||
|
||||
tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target,
|
||||
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_SYN_FLAG | TCP_ACK_FLAG);
|
||||
|
||||
tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target,
|
||||
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->c_seq + 1, instance->s_seq + 1, TCP_ACK_FLAG);
|
||||
|
||||
instance->s_seq++;
|
||||
@@ -270,23 +272,44 @@ void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance)
|
||||
void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance,
|
||||
const char * data, unsigned int datalen, enum tfe_conn_dir dir)
|
||||
{
|
||||
if (data == NULL || datalen == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dir == CONN_DIR_DOWNSTREAM)
|
||||
{
|
||||
tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->c_seq, instance->s_seq + 1, TCP_ACK_FLAG);
|
||||
|
||||
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
||||
data, datalen, instance->c_seq, instance->s_seq, TCP_ACK_FLAG);
|
||||
instance->c_seq += datalen;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_ACK_FLAG);
|
||||
|
||||
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
||||
data, datalen, instance->s_seq, instance->c_seq, TCP_ACK_FLAG);
|
||||
instance->s_seq += datalen;
|
||||
}
|
||||
}
|
||||
|
||||
void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance)
|
||||
{
|
||||
return;
|
||||
/* C->S FIN */
|
||||
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->c_seq, instance->s_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
|
||||
|
||||
/* C->S FIN, ACK */
|
||||
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_ACK_FLAG);
|
||||
|
||||
instance->c_seq += 1;
|
||||
|
||||
/* S->C FIN */
|
||||
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->s_seq, instance->c_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
|
||||
|
||||
/* C->S FIN, ACK */
|
||||
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
||||
NULL, 0, instance->c_seq, instance->s_seq + 1, TCP_ACK_FLAG);
|
||||
|
||||
instance->s_seq += 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user