TSG-13157 Decrypted Traffic Steering构造的SYN/SYN ACK支持窗口扩大选项

This commit is contained in:
luwenpeng
2022-12-26 14:31:22 +08:00
parent da468bbf67
commit 29a75b1d9c
3 changed files with 106 additions and 55 deletions

View File

@@ -278,11 +278,23 @@ static void tcp_restore_info_parse_from_pkt(struct pkt_info *pktinfo, struct tcp
}
}
struct tcp_option_window_scale{
uint8_t kind;
uint8_t length;
uint8_t shift_count;
};
static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info)
{
char buffer[1500] = {0};
int length = 0;
char tcp_option_buffer_c[40] = {0};
char tcp_option_buffer_s[40] = {0};
int tcp_option_length_c = 0;
int tcp_option_length_s = 0;
int options_padding_size = 0;
const struct tcp_restore_endpoint *client = &restore_info->client;
const struct tcp_restore_endpoint *server = &restore_info->server;
struct raw_socket *raw_socket_c = raw_socket_create(proxy->traffic_steering_options.device_client, proxy->traffic_steering_options.so_mask_client);
@@ -298,6 +310,34 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
uint32_t c_seq = client->seq - 1;
uint32_t s_seq = server->seq - 1;
/*
* Window Scale option (WSopt): Kind: 3, Length: 3
* +---------+---------+---------+
* | Kind=3 |Length=3 |shift.cnt|
* +---------+---------+---------+
* 1 1 1
*/
if (client->wscale_perm && server->wscale_perm)
{
// padding
memset(tcp_option_buffer_c + tcp_option_length_c, 1, 1);
tcp_option_length_c += 1;
memset(tcp_option_buffer_s + tcp_option_length_s, 1, 1);
tcp_option_length_s += 1;
struct tcp_option_window_scale *option_c = (struct tcp_option_window_scale *)(tcp_option_buffer_c + tcp_option_length_c);
option_c->kind = 3;
option_c->length = 3;
option_c->shift_count = client->wscale;
tcp_option_length_c += sizeof(struct tcp_option_window_scale);
struct tcp_option_window_scale *option_s = (struct tcp_option_window_scale *)(tcp_option_buffer_s + tcp_option_length_s);
option_s->kind = 3;
option_s->length = 3;
option_s->shift_count = server->wscale;
tcp_option_length_s += sizeof(struct tcp_option_window_scale);
}
if (client->addr.ss_family == AF_INET6)
{
struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr;
@@ -307,31 +347,34 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
// C -> S
length = tcp_packet_v6_construct(
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP
NULL, 0);
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
tcp_option_buffer_c, tcp_option_length_c, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_c, buffer, length);
c_seq += 1;
// S -> C
length = tcp_packet_v6_construct(
buffer, // buffer
&raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_server->sin6_addr, &sk_client->sin6_addr, 65, // IPv6
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP
NULL, 0);
buffer, // buffer
&raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_server->sin6_addr, &sk_client->sin6_addr, 65, // IPv6
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
tcp_option_buffer_s, tcp_option_length_s, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_s, buffer, length);
s_seq += 1;
// C -> S
length = tcp_packet_v6_construct(
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP
NULL, 0);
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP Header
NULL, 0, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_c, buffer, length);
}
else
@@ -346,7 +389,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x11, // IPv4
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP
port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
tcp_option_buffer_c, tcp_option_length_c, // TCP Options
NULL, 0);
raw_socket_send(raw_socket_c, buffer, length);
c_seq += 1;
@@ -356,17 +400,19 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer
&raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IP, // Ether
&sk_server->sin_addr,&sk_client->sin_addr, 0, 65, 0x12, // IPv4
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
tcp_option_buffer_s, tcp_option_length_s, // TCP Options
NULL, 0);
raw_socket_send(raw_socket_s, buffer, length);
s_seq += 1;
// C -> S
length = tcp_packet_v4_construct(
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x13, // IPv4
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP
buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x13, // IPv4
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP Header
NULL, 0, // TCP Options
NULL, 0);
raw_socket_send(raw_socket_c, buffer, length);
}