local:local socket sendto with adding binding path info

For udp localsocket current implementation,the sent information only carries the packet info.
The receiver receives the information,it don't know who the information comes from.
Thus the receiver doesn't know who to send the response message to.

We add sender's binding path info in the information,the receiver knows who sent the information
based on the parsed information.
The receiver knows who to send the response message to.

Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
wangchen 2024-01-31 19:00:33 +08:00 committed by Alan Carvalho de Assis
parent a591adc6d5
commit 9147c955dc
6 changed files with 205 additions and 144 deletions

View File

@ -122,9 +122,6 @@ struct local_conn_s
char lc_path[UNIX_PATH_MAX]; /* Path assigned by bind() */
int32_t lc_instance_id; /* Connection instance ID for stream
* server<->client connection pair */
#ifdef CONFIG_NET_LOCAL_DGRAM
uint16_t pktlen; /* Read-ahead packet length */
#endif /* CONFIG_NET_LOCAL_DGRAM */
FAR struct local_conn_s *
lc_peer; /* Peer connection instance */
@ -437,6 +434,30 @@ int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
ssize_t local_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
int flags);
/****************************************************************************
* Name: local_send_preamble
*
* Description:
* Send a packet on the write-only FIFO.
*
* Input Parameters:
* conn A reference to local connection structure
* filep File structure of write-only FIFO.
* buf Data to send
* len Length of data to send
* preamble preamble Flag to indicate the preamble sync header assembly
*
* Returned Value:
* Packet length is returned on success; a negated errno value is returned
* on any failure.
*
****************************************************************************/
int local_send_preamble(FAR struct local_conn_s *conn,
FAR struct file *filep,
FAR const struct iovec *buf,
size_t len);
/****************************************************************************
* Name: local_send_packet
*
@ -447,7 +468,6 @@ ssize_t local_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
* filep File structure of write-only FIFO.
* buf Data to send
* len Length of data to send
* preamble Flag to indicate the preamble sync header assembly
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
@ -456,7 +476,7 @@ ssize_t local_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
****************************************************************************/
int local_send_packet(FAR struct file *filep, FAR const struct iovec *buf,
size_t len, bool preamble);
size_t len);
/****************************************************************************
* Name: local_recvmsg
@ -530,23 +550,6 @@ int local_fifo_read(FAR struct file *filep, FAR uint8_t *buf,
int local_getaddr(FAR struct local_conn_s *conn, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
/****************************************************************************
* Name: local_sync
*
* Description:
* Read a sync bytes until the start of the packet is found.
*
* Input Parameters:
* filep - File structure of write-only FIFO.
*
* Returned Value:
* The non-zero size of the following packet is returned on success; a
* negated errno value is returned on any failure.
*
****************************************************************************/
int local_sync(FAR struct file *filep);
/****************************************************************************
* Name: local_create_fifos
*

View File

@ -686,7 +686,7 @@ int local_open_receiver(FAR struct local_conn_s *conn, bool nonblock)
*/
ret = local_set_pollinthreshold(&conn->lc_infile,
sizeof(uint16_t));
2 * sizeof(uint16_t));
}
}
@ -729,7 +729,7 @@ int local_open_sender(FAR struct local_conn_s *conn, FAR const char *path,
*/
ret = local_set_polloutthreshold(&conn->lc_outfile,
sizeof(uint16_t));
2 * sizeof(uint16_t));
}
}

View File

@ -56,7 +56,8 @@
****************************************************************************/
static int psock_fifo_read(FAR struct socket *psock, FAR void *buf,
FAR size_t *readlen, int flags, bool once)
size_t offset, FAR size_t *readlen,
int flags, bool once)
{
FAR struct local_conn_s *conn = psock->s_conn;
int ret;
@ -66,6 +67,7 @@ static int psock_fifo_read(FAR struct socket *psock, FAR void *buf,
struct pipe_peek_s peek =
{
buf,
offset,
*readlen
};
@ -270,7 +272,7 @@ psock_stream_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
/* Read the packet */
ret = psock_fifo_read(psock, buf, &readlen, flags, true);
ret = psock_fifo_read(psock, buf, 0, &readlen, flags, true);
if (ret < 0)
{
return ret;
@ -291,6 +293,56 @@ psock_stream_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
}
#endif /* CONFIG_NET_LOCAL_STREAM */
/****************************************************************************
* Name: psock_fifo_discard
*
* Description:
* psock_fifo_discard() discard buffer from a local socket.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* len Remaining length of buffer
* flags Receive flags
*
* Returned Value:
* On success, returns OK. Otherwise, on errors, errno is returned
*
****************************************************************************/
#ifdef CONFIG_NET_LOCAL_DGRAM
static int psock_fifo_discard(FAR struct socket *psock, size_t len,
int flags)
{
uint8_t bitbucket[256];
size_t tmplen;
int ret;
if (flags & MSG_PEEK)
{
return OK;
}
while (len > 0)
{
/* Read 256 bytes into the bit bucket */
tmplen = MIN(len, sizeof(bitbucket));
ret = psock_fifo_read(psock, bitbucket, 0, &tmplen, flags, false);
if (ret < 0)
{
nerr("ERROR: Failed to get bitbucket : ret %d\n", ret);
return ret;
}
/* Adjust the number of bytes len to be read from the packet */
DEBUGASSERT(tmplen <= len);
len -= tmplen;
}
return OK;
}
/****************************************************************************
* Name: psock_dgram_recvfrom
*
@ -312,7 +364,6 @@ psock_stream_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
*
****************************************************************************/
#ifdef CONFIG_NET_LOCAL_DGRAM
static inline ssize_t
psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
int flags, FAR struct sockaddr *from,
@ -320,8 +371,12 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
{
FAR struct local_conn_s *conn = psock->s_conn;
size_t readlen;
size_t pathlen;
bool bclose = false;
int ret = 0;
uint16_t addrlen;
uint16_t pktlen;
int offset = 0;
int ret;
/* We keep packet sizes in a uint16_t, so there is a upper limit to the
* 'len' that can be supported.
@ -366,33 +421,65 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
}
}
readlen = sizeof(addrlen);
ret = psock_fifo_read(psock, &addrlen, offset, &readlen, flags, false);
if (ret < 0)
{
nerr("ERROR: Failed to get path length: ret %d\n", ret);
return ret;
}
/* Sync to the start of the next packet in the stream and get the size of
* the next packet.
*/
if (conn->pktlen <= 0)
readlen = sizeof(pktlen);
offset += sizeof(addrlen);
ret = psock_fifo_read(psock, &pktlen, offset, &readlen, flags, false);
if (ret < 0)
{
ret = local_sync(&conn->lc_infile);
nerr("ERROR: Failed to get packet length: ret %d\n", ret);
goto errout_with_infd;
}
readlen = addrlen;
offset += sizeof(pktlen);
if (from && fromlen && *fromlen)
{
pathlen = MIN(*fromlen - 1, readlen);
ret = psock_fifo_read(psock, from->sa_data, offset,
&pathlen, flags, false);
if (ret < 0)
{
nerr("ERROR: Failed to get packet length: %d\n", ret);
goto errout_with_infd;
}
else if (ret > UINT16_MAX)
{
nerr("ERROR: Packet is too big: %d\n", ret);
nerr("ERROR: Failed to get path : ret %d\n", ret);
goto errout_with_infd;
}
conn->pktlen = ret;
from->sa_family = AF_LOCAL;
from->sa_data[pathlen] = '\0';
*fromlen = pathlen;
readlen -= pathlen;
}
if (readlen)
{
ret = psock_fifo_discard(psock, readlen, flags);
if (ret < 0)
{
nerr("ERROR: Failed to discard redunance address: ret %d\n", ret);
goto errout_with_infd;
}
}
/* Read the packet */
readlen = MIN(conn->pktlen, len);
ret = psock_fifo_read(psock, buf, &readlen, flags, false);
readlen = MIN(pktlen, len);
offset += addrlen;
ret = psock_fifo_read(psock, buf, offset, &readlen, flags, false);
if (ret < 0)
{
nerr("ERROR: Failed to get packet : ret %d\n", ret);
goto errout_with_infd;
}
@ -400,55 +487,10 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* of the packet to the bit bucket.
*/
if (flags & MSG_PEEK)
DEBUGASSERT(readlen <= pktlen);
if (readlen < pktlen)
{
goto skip_flush;
}
DEBUGASSERT(readlen <= conn->pktlen);
if (readlen < conn->pktlen)
{
uint8_t bitbucket[32];
uint16_t remaining;
size_t tmplen;
remaining = conn->pktlen - readlen;
do
{
/* Read 32 bytes into the bit bucket */
tmplen = MIN(remaining, 32);
ret = psock_fifo_read(psock, bitbucket, &tmplen, flags, false);
if (ret < 0)
{
goto errout_with_infd;
}
/* Adjust the number of bytes remaining to be read from the
* packet
*/
DEBUGASSERT(tmplen <= remaining);
remaining -= tmplen;
}
while (remaining > 0);
}
/* The fifo has been read and the pktlen needs to be cleared */
conn->pktlen = 0;
skip_flush:
/* Return the address family */
if (from)
{
ret = local_getaddr(conn, from, fromlen);
if (ret < 0)
{
return ret;
}
ret = psock_fifo_discard(psock, pktlen - readlen, flags);
}
errout_with_infd:

View File

@ -121,34 +121,6 @@ errout:
return ret;
}
/****************************************************************************
* Name: local_sync
*
* Description:
* Read a sync bytes until the start of the packet is found.
*
* Input Parameters:
* filep - File structure of write-only FIFO.
*
* Returned Value:
* The non-zero size of the following packet is returned on success; a
* negated errno value is returned on any failure.
*
****************************************************************************/
int local_sync(FAR struct file *filep)
{
size_t readlen;
uint16_t pktlen;
int ret;
/* Read the packet length */
readlen = sizeof(uint16_t);
ret = local_fifo_read(filep, (FAR uint8_t *)&pktlen, &readlen, false);
return ret < 0 ? ret : pktlen;
}
/****************************************************************************
* Name: local_getaddr
*

View File

@ -210,8 +210,7 @@ static ssize_t local_send(FAR struct socket *psock,
return ret;
}
ret = local_send_packet(&conn->lc_outfile, buf, len,
psock->s_type == SOCK_DGRAM);
ret = local_send_packet(&conn->lc_outfile, buf, len);
nxmutex_unlock(&conn->lc_sendlock);
}
break;
@ -325,7 +324,7 @@ static ssize_t local_sendto(FAR struct socket *psock,
if (ret < 0)
{
nerr("ERROR: Failed to create FIFO for %s: %zd\n",
conn->lc_path, ret);
unaddr->sun_path, ret);
return ret;
}
@ -352,9 +351,17 @@ static ssize_t local_sendto(FAR struct socket *psock,
goto errout_with_sender;
}
/* Send the preamble */
ret = local_send_preamble(conn, &conn->lc_outfile, buf, len);
if (ret < 0)
{
nerr("ERROR: Failed to send the preamble: %zd\n", ret);
}
/* Send the packet */
ret = local_send_packet(&conn->lc_outfile, buf, len, true);
ret = local_send_packet(&conn->lc_outfile, buf, len);
if (ret < 0)
{
nerr("ERROR: Failed to send the packet: %zd\n", ret);

View File

@ -93,6 +93,66 @@ static int local_fifo_write(FAR struct file *filep, FAR const uint8_t *buf,
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: local_send_preamble
*
* Description:
* Send a packet on the write-only FIFO.
*
* Input Parameters:
* conn A reference to local connection structure
* filep File structure of write-only FIFO.
* buf Data to send
* len Length of data to send
*
* Returned Value:
* Packet length is returned on success; a negated errno value is returned
* on any failure.
*
****************************************************************************/
int local_send_preamble(FAR struct local_conn_s *conn,
FAR struct file *filep,
FAR const struct iovec *buf,
size_t len)
{
FAR const struct iovec *end = buf + len;
FAR const struct iovec *iov;
int ret;
uint16_t len16 = strlen(conn->lc_path);
ret = local_fifo_write(&conn->lc_outfile, (FAR const uint8_t *)&len16,
sizeof(uint16_t));
if (ret != sizeof(uint16_t))
{
nerr("ERROR: local send path length failed ret: %d\n", ret);
return ret;
}
/* Send the packet length */
for (len16 = 0, iov = buf; iov != end; iov++)
{
len16 += iov->iov_len;
}
if (len16 > LOCAL_SEND_LIMIT)
{
nerr("ERROR: Packet is too big: %d\n", len16);
return -EMSGSIZE;
}
ret = local_fifo_write(filep, (FAR const uint8_t *)&len16,
sizeof(uint16_t));
if (ret != sizeof(uint16_t))
{
return ret;
}
return local_fifo_write(&conn->lc_outfile, (uint8_t *)conn->lc_path,
strlen(conn->lc_path));
}
/****************************************************************************
* Name: local_send_packet
*
@ -103,7 +163,6 @@ static int local_fifo_write(FAR struct file *filep, FAR const uint8_t *buf,
* filep File structure of write-only FIFO.
* buf Data to send
* len Length of data to send
* preamble Flag to indicate the preamble sync header assembly
*
* Returned Value:
* Packet length is returned on success; a negated errno value is returned
@ -112,41 +171,19 @@ static int local_fifo_write(FAR struct file *filep, FAR const uint8_t *buf,
****************************************************************************/
int local_send_packet(FAR struct file *filep, FAR const struct iovec *buf,
size_t len, bool preamble)
size_t len)
{
FAR const struct iovec *end = buf + len;
FAR const struct iovec *iov;
int ret = -EINVAL;
uint16_t len16;
if (preamble)
{
/* Send the packet length */
for (len16 = 0, iov = buf; iov != end; iov++)
{
len16 += iov->iov_len;
}
if (len16 > LOCAL_SEND_LIMIT)
{
nerr("ERROR: Packet is too big: %d\n", len16);
return -EMSGSIZE;
}
ret = local_fifo_write(filep, (FAR const uint8_t *)&len16,
sizeof(uint16_t));
if (ret != sizeof(uint16_t))
{
return ret;
}
}
for (len16 = 0, iov = buf; iov != end; iov++)
{
ret = local_fifo_write(filep, iov->iov_base, iov->iov_len);
if (ret < 0)
{
nerr("ERROR: local send packet failed ret: %d\n", ret);
break;
}