From 9147c955dc16933d2bf55f9c646496dbc15a65b3 Mon Sep 17 00:00:00 2001 From: wangchen Date: Wed, 31 Jan 2024 19:00:33 +0800 Subject: [PATCH] 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 --- net/local/local.h | 47 +++++----- net/local/local_fifo.c | 4 +- net/local/local_recvmsg.c | 168 ++++++++++++++++++++++------------- net/local/local_recvutils.c | 28 ------ net/local/local_sendmsg.c | 15 +++- net/local/local_sendpacket.c | 87 ++++++++++++------ 6 files changed, 205 insertions(+), 144 deletions(-) diff --git a/net/local/local.h b/net/local/local.h index 6b57249f84..29950f6ea3 100644 --- a/net/local/local.h +++ b/net/local/local.h @@ -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 * diff --git a/net/local/local_fifo.c b/net/local/local_fifo.c index 48776cf647..1cc96c1052 100644 --- a/net/local/local_fifo.c +++ b/net/local/local_fifo.c @@ -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)); } } diff --git a/net/local/local_recvmsg.c b/net/local/local_recvmsg.c index a0632699b4..3f977d9686 100644 --- a/net/local/local_recvmsg.c +++ b/net/local/local_recvmsg.c @@ -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: diff --git a/net/local/local_recvutils.c b/net/local/local_recvutils.c index 0fee12fae9..0208249879 100644 --- a/net/local/local_recvutils.c +++ b/net/local/local_recvutils.c @@ -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 * diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c index 81dad3e576..badea5a70b 100644 --- a/net/local/local_sendmsg.c +++ b/net/local/local_sendmsg.c @@ -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); diff --git a/net/local/local_sendpacket.c b/net/local/local_sendpacket.c index 5933b174ee..2f9c6f42ec 100644 --- a/net/local/local_sendpacket.c +++ b/net/local/local_sendpacket.c @@ -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; }