net: tcp2: Refactor tcp_out()

In order to support the data retransmission, refactor tcp_out()
into tcp_out_ext() which supports passing the sequence number.

In addition drop modifications of the connection sequence number
from tcp_out_ext(), this is the responsibility of data retransmission.

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
This commit is contained in:
Oleg Zhurakivskyy 2020-05-13 17:33:53 +03:00 committed by Carles Cufí
commit 5b54daea36

View file

@ -505,7 +505,8 @@ static int tcp_finalize_pkt(struct net_pkt *pkt)
return -EINVAL; return -EINVAL;
} }
static int tcp_header_add(struct tcp *conn, struct net_pkt *pkt, u8_t flags) static int tcp_header_add(struct tcp *conn, struct net_pkt *pkt, u8_t flags,
u32_t seq)
{ {
NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct tcphdr); NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct tcphdr);
struct tcphdr *th; struct tcphdr *th;
@ -523,7 +524,7 @@ static int tcp_header_add(struct tcp *conn, struct net_pkt *pkt, u8_t flags)
th->th_off = 5; th->th_off = 5;
th->th_flags = flags; th->th_flags = flags;
th->th_win = htons(conn->win); th->th_win = htons(conn->win);
th->th_seq = htonl(conn->seq); th->th_seq = htonl(seq);
if (ACK & flags) { if (ACK & flags) {
th->th_ack = htonl(conn->ack); th->th_ack = htonl(conn->ack);
@ -549,49 +550,40 @@ static int ip_header_add(struct tcp *conn, struct net_pkt *pkt)
return -EINVAL; return -EINVAL;
} }
static void tcp_out(struct tcp *conn, u8_t flags, ...) static void tcp_out_ext(struct tcp *conn, u8_t flags, struct net_pkt *data,
u32_t seq)
{ {
struct net_pkt *pkt; struct net_pkt *pkt;
size_t len = 0; int ret;
int r;
pkt = tcp_pkt_alloc(conn, sizeof(struct tcphdr)); pkt = tcp_pkt_alloc(conn, sizeof(struct tcphdr));
if (!pkt) { if (!pkt) {
goto fail; goto out;
} }
if (PSH & flags) { if (data) {
struct net_pkt *data_pkt; /* Append the data buffer to the pkt */
va_list ap; net_pkt_append_buffer(pkt, data->buffer);
va_start(ap, flags); data->buffer = NULL;
data_pkt = va_arg(ap, struct net_pkt *); tcp_pkt_unref(data);
va_end(ap);
len = net_pkt_get_len(data_pkt);
/* Append the data buffer to pkt */
net_pkt_append_buffer(pkt, data_pkt->buffer);
data_pkt->buffer = NULL;
tcp_pkt_unref(data_pkt);
} }
r = ip_header_add(conn, pkt); ret = ip_header_add(conn, pkt);
if (r < 0) { if (ret < 0) {
goto fail; tcp_pkt_unref(pkt);
goto out;
} }
r = tcp_header_add(conn, pkt, flags); ret = tcp_header_add(conn, pkt, flags, seq);
if (r < 0) { if (ret < 0) {
goto fail; tcp_pkt_unref(pkt);
goto out;
} }
r = tcp_finalize_pkt(pkt); ret = tcp_finalize_pkt(pkt);
if (r < 0) { if (ret < 0) {
goto fail; tcp_pkt_unref(pkt);
} goto out;
if (len) {
conn_seq(conn, + len);
} }
NET_DBG("%s", log_strdup(tcp_th(pkt))); NET_DBG("%s", log_strdup(tcp_th(pkt)));
@ -606,11 +598,11 @@ static void tcp_out(struct tcp *conn, u8_t flags, ...)
tcp_send_process((struct k_work *)&conn->send_timer); tcp_send_process((struct k_work *)&conn->send_timer);
out: out:
return; return;
}
fail: static void tcp_out(struct tcp *conn, u8_t flags)
if (pkt) { {
tcp_pkt_unref(pkt); tcp_out_ext(conn, flags, NULL /* no data */, conn->seq);
}
} }
static void tcp_timewait_timeout(struct k_work *work) static void tcp_timewait_timeout(struct k_work *work)