diff --git a/platform/src/acceptor_kni_v3.cpp b/platform/src/acceptor_kni_v3.cpp index 512cc71..5a81848 100644 --- a/platform/src/acceptor_kni_v3.cpp +++ b/platform/src/acceptor_kni_v3.cpp @@ -284,6 +284,11 @@ struct tcp_option_window_scale{ uint8_t shift_count; }; +struct tcp_option_sack{ + uint8_t kind; + uint8_t length; +}; + static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info) { char buffer[1500] = {0}; @@ -338,6 +343,32 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info * tcp_option_length_s += sizeof(struct tcp_option_window_scale); } + /* + * SACK option: Kind: 4, Length: 2 + * +---------+---------+ + * | Kind=4 |Length=2 | + * +---------+---------+ + * 1 1 + */ + if (client->sack_perm && server->sack_perm) + { + // padding + memset(tcp_option_buffer_c + tcp_option_length_c, 1, 2); + tcp_option_length_c += 2; + memset(tcp_option_buffer_s + tcp_option_length_s, 1, 2); + tcp_option_length_s += 2; + + struct tcp_option_sack *option_c = (struct tcp_option_sack *)(tcp_option_buffer_c + tcp_option_length_c); + option_c->kind = 4; + option_c->length = 2; + tcp_option_length_c += sizeof(struct tcp_option_sack); + + struct tcp_option_sack *option_s = (struct tcp_option_sack *)(tcp_option_buffer_s + tcp_option_length_s); + option_s->kind = 4; + option_s->length = 2; + tcp_option_length_s += sizeof(struct tcp_option_sack); + } + if (client->addr.ss_family == AF_INET6) { struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr; @@ -372,7 +403,7 @@ 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_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 + port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP Header NULL, 0, // TCP Options NULL, 0); // Payload raw_socket_send(raw_socket_c, buffer, length);