net: tcp2: Eliminate the need for a test send window
In order to drop dependency on a heap, drop the test send window. Use net_tcp_queue_data() to receive the outgoing data from the socket layer. Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
This commit is contained in:
parent
b25faa6159
commit
16b8244cf8
3 changed files with 44 additions and 87 deletions
|
@ -1572,14 +1572,7 @@ static int context_sendto(struct net_context *context,
|
|||
ret = net_send_data(pkt);
|
||||
} else if (IS_ENABLED(CONFIG_NET_TCP) &&
|
||||
net_context_get_ip_proto(context) == IPPROTO_TCP) {
|
||||
#if IS_ENABLED(CONFIG_NET_TCP2)
|
||||
ret = net_tcp_queue(context, buf, len, msghdr);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
#else
|
||||
ret = context_write_data(pkt, buf, len, msghdr);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
|
@ -1590,7 +1583,6 @@ static int context_sendto(struct net_context *context,
|
|||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = net_tcp_send_data(context, cb, user_data);
|
||||
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
|
||||
|
|
|
@ -266,8 +266,6 @@ static int tcp_conn_unref(struct tcp *conn)
|
|||
|
||||
tcp_send_queue_flush(conn);
|
||||
|
||||
tcp_win_free(conn->snd, "SND");
|
||||
|
||||
tcp_free(conn->src);
|
||||
tcp_free(conn->dst);
|
||||
|
||||
|
@ -541,21 +539,26 @@ static size_t tcp_data_get(struct tcp *conn, struct net_pkt *pkt)
|
|||
|
||||
static void tcp_header_add(struct tcp *conn, struct net_pkt *pkt, u8_t flags)
|
||||
{
|
||||
struct tcphdr *th = th_get(pkt);
|
||||
struct net_buf *buf = net_pkt_get_frag(pkt, K_NO_WAIT);
|
||||
struct tcphdr th;
|
||||
|
||||
memset(th, 0, sizeof(*th));
|
||||
memset(&th, 0, sizeof(th));
|
||||
|
||||
th->th_sport = conn->src->sin.sin_port;
|
||||
th->th_dport = conn->dst->sin.sin_port;
|
||||
th.th_sport = conn->src->sin.sin_port;
|
||||
th.th_dport = conn->dst->sin.sin_port;
|
||||
|
||||
th->th_off = 5;
|
||||
th->th_flags = flags;
|
||||
th->th_win = htons(conn->win);
|
||||
th->th_seq = htonl(conn->seq);
|
||||
th.th_off = 5;
|
||||
th.th_flags = flags;
|
||||
th.th_win = htons(conn->win);
|
||||
th.th_seq = htonl(conn->seq);
|
||||
|
||||
if (ACK & flags) {
|
||||
th->th_ack = htonl(conn->ack);
|
||||
th.th_ack = htonl(conn->ack);
|
||||
}
|
||||
|
||||
memcpy(net_buf_add(buf, sizeof(th)), &th, sizeof(th));
|
||||
|
||||
net_pkt_frag_insert(pkt, buf);
|
||||
}
|
||||
|
||||
static void ip_header_add(struct tcp *conn, struct net_pkt *pkt)
|
||||
|
@ -612,17 +615,6 @@ static void ip_header_add(struct tcp *conn, struct net_pkt *pkt)
|
|||
}
|
||||
}
|
||||
|
||||
static struct net_pkt *tcp_pkt_make(struct tcp *conn, u8_t flags)
|
||||
{
|
||||
struct net_pkt *pkt = tcp_pkt_alloc(sizeof(struct tcphdr));
|
||||
|
||||
tcp_header_add(conn, pkt, flags);
|
||||
|
||||
pkt->iface = conn->iface;
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
static void tcp_chain_free(struct net_buf *head)
|
||||
{
|
||||
struct net_buf *next;
|
||||
|
@ -650,31 +642,38 @@ static void tcp_chain(struct net_pkt *pkt, struct net_buf *head)
|
|||
|
||||
static void tcp_out(struct tcp *conn, u8_t flags, ...)
|
||||
{
|
||||
struct net_pkt *pkt = tcp_pkt_make(conn, flags);
|
||||
struct net_pkt *pkt;
|
||||
size_t len = 0;
|
||||
|
||||
if (PSH & flags) {
|
||||
size_t len = conn->snd->len;
|
||||
struct net_buf *buf = tcp_win_peek(conn, conn->snd, "SND", len);
|
||||
|
||||
{
|
||||
va_list ap;
|
||||
ssize_t *out_len;
|
||||
|
||||
va_start(ap, flags);
|
||||
out_len = va_arg(ap, ssize_t *);
|
||||
*out_len = len;
|
||||
pkt = va_arg(ap, struct net_pkt *);
|
||||
va_end(ap);
|
||||
|
||||
len = net_pkt_get_len(pkt);
|
||||
} else {
|
||||
pkt = tcp_pkt_alloc(0);
|
||||
}
|
||||
|
||||
tcp_chain(pkt, buf);
|
||||
pkt->iface = conn->iface;
|
||||
|
||||
tcp_chain_free(buf);
|
||||
}
|
||||
tcp_header_add(conn, pkt, flags);
|
||||
|
||||
ip_header_add(conn, pkt);
|
||||
|
||||
net_pkt_cursor_init(pkt);
|
||||
net_pkt_set_overwrite(pkt, true);
|
||||
|
||||
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||
net_pkt_ip_opts_len(pkt));
|
||||
|
||||
net_tcp_finalize(pkt);
|
||||
|
||||
if (len) {
|
||||
conn_seq(conn, + len);
|
||||
}
|
||||
|
||||
NET_DBG("%s", log_strdup(tcp_th(pkt)));
|
||||
|
||||
if (tcp_send_cb) {
|
||||
|
@ -712,8 +711,6 @@ static struct tcp *tcp_conn_alloc(void)
|
|||
|
||||
conn->win = tcp_window;
|
||||
|
||||
conn->snd = tcp_win_new();
|
||||
|
||||
sys_slist_init(&conn->send_queue);
|
||||
|
||||
k_delayed_work_init(&conn->send_timer, tcp_send_process);
|
||||
|
@ -987,13 +984,6 @@ next_state:
|
|||
}
|
||||
break;
|
||||
case TCP_ESTABLISHED:
|
||||
if (!th && conn->snd->len) { /* TODO: Out of the loop */
|
||||
ssize_t data_len;
|
||||
|
||||
tcp_out(conn, PSH | ACK, &data_len);
|
||||
conn_seq(conn, + data_len);
|
||||
break;
|
||||
}
|
||||
/* full-close */
|
||||
if (FL(&fl, ==, (FIN | ACK), th_seq(th) == conn->ack)) {
|
||||
conn_ack(conn, + 1);
|
||||
|
@ -1112,48 +1102,24 @@ int net_tcp_update_recv_wnd(struct net_context *context, s32_t delta)
|
|||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
int net_tcp_queue(struct net_context *context, const void *buf, size_t len,
|
||||
const struct msghdr *msghdr)
|
||||
/* net context wants to queue data for the TCP connection */
|
||||
int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt)
|
||||
{
|
||||
struct tcp *conn = context->tcp;
|
||||
ssize_t ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
NET_DBG("conn: %p, buf: %p, len: %zu", conn, buf, len);
|
||||
NET_DBG("conn: %p, len: %zu", conn, net_pkt_get_len(pkt));
|
||||
|
||||
if (conn == NULL) {
|
||||
ret = -ESHUTDOWN;
|
||||
if (!conn || conn->state != TCP_ESTABLISHED) {
|
||||
ret = -ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (msghdr && msghdr->msg_iovlen > 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < msghdr->msg_iovlen; i++) {
|
||||
ret = _tcp_send(conn, msghdr->msg_iov[i].iov_base,
|
||||
msghdr->msg_iov[i].iov_len, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = _tcp_send(conn, buf, len, 0);
|
||||
}
|
||||
tcp_out(conn, PSH | ACK, pkt);
|
||||
out:
|
||||
NET_DBG("conn: %p, ret: %zd", conn, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* net context wants to queue data for the TCP connection - not used */
|
||||
int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt)
|
||||
{
|
||||
ARG_UNUSED(context);
|
||||
ARG_UNUSED(pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* net context is about to send out queued data - inform caller only */
|
||||
int net_tcp_send_data(struct net_context *context, net_context_send_cb_t cb,
|
||||
void *user_data)
|
||||
|
|
|
@ -153,7 +153,6 @@ struct tcp { /* TCP connection */
|
|||
union tcp_endpoint *src;
|
||||
union tcp_endpoint *dst;
|
||||
u16_t win;
|
||||
struct tcp_win *snd;
|
||||
struct k_delayed_work send_timer;
|
||||
sys_slist_t send_queue;
|
||||
bool in_retransmission;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue