Commit 2eb1bef4 authored by Oleg Zhurakivskyy's avatar Oleg Zhurakivskyy Committed by Jukka Rissanen
Browse files

net: tcp2: Implement TCP data sending



Since TCP needs to be able to decide how much data is to be sent
in a TCP segment and when the segment needs to be sent, the TCP
data buffer needs to be passed down to the TCP stack. For tcp2
this causes a new function handling the data as a buffer or as an
iov to be implemented and only that function is called when
sending data out via the new TCP stack. net_tcp_send_data() is
invoked as the caller expects to be informed when the data has
been sent.

For the current stack keep the sending functions as is.

Signed-off-by: default avatarPatrik Flykt <patrik.flykt@intel.com>
Signed-off-by: default avatarOleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
parent bc69ae4f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -35,6 +35,10 @@ LOG_MODULE_REGISTER(net_ctx, CONFIG_NET_CONTEXT_LOG_LEVEL);
#include "tcp_internal.h"
#include "net_stats.h"

#if IS_ENABLED(CONFIG_NET_TCP2)
#include "tcp2.h"
#endif

#ifndef EPFNOSUPPORT
/* Some old versions of newlib haven't got this defined in errno.h,
 * Just use EPROTONOSUPPORT in this case
@@ -1565,6 +1569,14 @@ 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;
@@ -1575,6 +1587,7 @@ 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) &&
+42 −8
Original line number Diff line number Diff line
@@ -869,10 +869,9 @@ next_state:
	}
}

static ssize_t _tcp_send(int fd, const void *buf, size_t len, int flags)
static ssize_t _tcp_send(struct tcp *conn, const void *buf, size_t len,
				int flags)
{
	struct tcp *conn = (void *)sys_slist_peek_head(&tcp_conns);

	tcp_win_append(conn->snd, "SND", buf, len);

	tcp_in(conn, NULL);
@@ -930,20 +929,55 @@ 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)
{
	struct tcp *conn = context->tcp;
	ssize_t ret = 0;

	NET_DBG("conn: %p, buf: %p, len: %zu", conn, buf, len);

	if (conn == NULL) {
		ret = -ESHUTDOWN;
		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);
	}
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 -EPROTONOSUPPORT;
	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)
{
	ARG_UNUSED(context);
	ARG_UNUSED(cb);
	ARG_UNUSED(user_data);
	if (cb) {
		cb(context, 0, user_data);
	}

	return 0;
}
@@ -1314,7 +1348,7 @@ bool tp_input(struct net_pkt *pkt)
			tp_output(pkt->iface, buf, 1);
			responded = true;
			NET_DBG("tcp_send(\"%s\")", tp->data);
			_tcp_send(0, buf, len, 0);
			_tcp_send(conn, buf, len, 0);
		}
		break;
	case TP_CONFIG_REQUEST: