net: tcp2: Parse TCP options only once

Make sure we only parse the received TCP options only once. Store
the options to tcp conn struct for later use.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-04-22 15:19:52 +03:00
commit 291a4b2bd1
2 changed files with 21 additions and 6 deletions

View file

@ -376,7 +376,8 @@ static u8_t *tcp_options_get(struct net_pkt *pkt, int tcp_options_len)
return options;
}
static bool tcp_options_check(struct net_pkt *pkt, ssize_t len)
static bool tcp_options_check(struct tcp_options *recv_options,
struct net_pkt *pkt, ssize_t len)
{
bool result = len > 0 && ((len % 4) == 0) ? true : false;
u8_t *options = tcp_options_get(pkt, len);
@ -384,6 +385,9 @@ static bool tcp_options_check(struct net_pkt *pkt, ssize_t len)
NET_DBG("len=%zd", len);
recv_options->mss_found = false;
recv_options->wnd_found = false;
for ( ; len >= 1; options += opt_len, len -= opt_len) {
opt = options[0];
@ -414,12 +418,18 @@ static bool tcp_options_check(struct net_pkt *pkt, ssize_t len)
result = false;
goto end;
}
recv_options->mss = opt;
recv_options->mss_found = true;
break;
case TCPOPT_WINDOW:
if (opt_len != 3) {
result = false;
goto end;
}
recv_options->window = opt;
recv_options->wnd_found = true;
break;
default:
continue;
@ -440,10 +450,6 @@ static size_t tcp_data_len(struct net_pkt *pkt)
ssize_t len = net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) -
net_pkt_ip_opts_len(pkt) - sizeof(*th) - tcp_options_len;
if (tcp_options_len && !tcp_options_check(pkt, tcp_options_len)) {
len = 0;
}
return len > 0 ? len : 0;
}
@ -861,7 +867,8 @@ static void tcp_in(struct tcp *conn, struct net_pkt *pkt)
goto next_state;
}
if (tcp_options_len && !tcp_options_check(pkt, tcp_options_len)) {
if (tcp_options_len && !tcp_options_check(&conn->recv_options, pkt,
tcp_options_len)) {
NET_DBG("DROP: Invalid TCP option list");
tcp_out(conn, RST);
conn_state(conn, TCP_CLOSED);

View file

@ -120,6 +120,13 @@ union tcp_endpoint {
struct sockaddr_in6 sin6;
};
struct tcp_options {
u16_t mss;
u16_t window;
bool mss_found : 1;
bool wnd_found : 1;
};
struct tcp { /* TCP connection */
sys_snode_t next;
struct net_context *context;
@ -131,6 +138,7 @@ struct tcp { /* TCP connection */
union tcp_endpoint src;
union tcp_endpoint dst;
u16_t win;
struct tcp_options recv_options;
struct k_delayed_work send_timer;
sys_slist_t send_queue;
bool in_retransmission;