diff --git a/net/local/local.h b/net/local/local.h index 6b57249f842..29950f6ea3c 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 48776cf647a..1cc96c10520 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 a0632699b46..3f977d96868 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 0fee12fae9c..02082498794 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 81dad3e576a..badea5a70be 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 5933b174ee8..2f9c6f42ec2 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; }