usrsock_server: Use remain instead of iov[0] to figure out partial requests

Found a problem:

When sendto handler gets an error, it will release all its rx buffer,
then iov_base becomes NULL. But it cannot let client stop its request,
then the next data from client cannot be handled by usrsock server
correctly.

It's better to note down the remaining bytes, then we can stop at
correct time.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2023-03-31 16:49:25 +08:00 committed by Masayuki Ishikawa
parent b982c1747b
commit 0d118ec214

View File

@ -48,6 +48,7 @@
struct usrsock_rpmsg_s
{
rmutex_t mutex;
ssize_t remain;
struct iovec iov[CONFIG_NET_USRSOCK_RPMSG_SERVER_NIOVEC];
struct socket socks[CONFIG_NET_USRSOCK_RPMSG_SERVER_NSOCKS];
FAR struct rpmsg_endpoint *epts[CONFIG_NET_USRSOCK_RPMSG_SERVER_NSOCKS];
@ -382,21 +383,28 @@ static int usrsock_rpmsg_sendto_handler(FAR struct rpmsg_endpoint *ept,
FAR struct usrsock_rpmsg_s *priv = priv_;
uint16_t events = 0;
ssize_t ret = -EBADF;
size_t total;
int retr;
int i;
if (priv->iov[0].iov_base)
if (priv->remain > 0)
{
size_t hlen;
struct msghdr msg =
{
};
priv->remain -= len;
if (!priv->iov[0].iov_base)
{
/* Maybe error occurred previously, skip processing. */
return 0;
}
req = priv->iov[0].iov_base;
hlen = sizeof(*req) + req->addrlen;
total = len;
for (i = 0; i < CONFIG_NET_USRSOCK_RPMSG_SERVER_NIOVEC; i++)
{
if (!priv->iov[i].iov_base)
@ -406,8 +414,6 @@ static int usrsock_rpmsg_sendto_handler(FAR struct rpmsg_endpoint *ept,
rpmsg_hold_rx_buffer(ept, data);
break;
}
total += priv->iov[i].iov_len;
}
if (i == CONFIG_NET_USRSOCK_RPMSG_SERVER_NIOVEC)
@ -418,11 +424,11 @@ static int usrsock_rpmsg_sendto_handler(FAR struct rpmsg_endpoint *ept,
/* Partial packet ? continue to fetch */
if (req->buflen > total - hlen)
if (priv->remain > 0)
{
return 0;
}
else if (req->buflen < total - hlen)
else if (priv->remain < 0)
{
ret = -EINVAL;
goto out;
@ -452,8 +458,8 @@ static int usrsock_rpmsg_sendto_handler(FAR struct rpmsg_endpoint *ept,
if (req->usockid >= 0 &&
req->usockid < CONFIG_NET_USRSOCK_RPMSG_SERVER_NSOCKS)
{
total = sizeof(*req) + req->addrlen + req->buflen;
if (total > len)
priv->remain = sizeof(*req) + req->addrlen + req->buflen - len;
if (priv->remain > 0)
{
priv->iov[0].iov_base = data;
priv->iov[0].iov_len = len;
@ -1010,7 +1016,7 @@ static int usrsock_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
FAR struct usrsock_request_common_s *common = data;
FAR struct usrsock_rpmsg_s *priv = priv_;
if (priv->iov[0].iov_base)
if (priv->remain > 0)
{
return usrsock_rpmsg_sendto_handler(ept, data, len, src, priv);
}