From a7a47621fa403df6c76c394d8bb31276cf07853f Mon Sep 17 00:00:00 2001 From: liqinhui Date: Tue, 27 Jun 2023 16:28:09 +0800 Subject: [PATCH] net/local: Support the socketpair interface of local udp socket. Add the proccessing logic of udp socketpair, and modify the logic of sending and receiving for udp socketpair. Verification: - Use the socketpair interface to create a pair of local udp sockets, and perform read and write operations. Signed-off-by: liqinhui --- net/local/local.h | 25 +++++++------- net/local/local_fifo.c | 44 ++++++++++++++---------- net/local/local_recvmsg.c | 72 +++++++++++++++++++-------------------- net/local/local_release.c | 13 +------ net/local/local_sendmsg.c | 21 ++++-------- net/local/local_sockif.c | 32 ++++++++--------- 6 files changed, 96 insertions(+), 111 deletions(-) diff --git a/net/local/local.h b/net/local/local.h index 6b6bb65cc81..b437dd463d0 100644 --- a/net/local/local.h +++ b/net/local/local.h @@ -490,9 +490,7 @@ int local_sync(FAR struct file *filep); * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_create_fifos(FAR struct local_conn_s *conn); -#endif /**************************************************************************** * Name: local_create_halfduplex @@ -515,9 +513,7 @@ int local_create_halfduplex(FAR struct local_conn_s *conn, * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_release_fifos(FAR struct local_conn_s *conn); -#endif /**************************************************************************** * Name: local_release_halfduplex @@ -539,9 +535,7 @@ int local_release_halfduplex(FAR struct local_conn_s *conn); * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_client_rx(FAR struct local_conn_s *client, bool nonblock); -#endif /**************************************************************************** * Name: local_open_client_tx @@ -551,9 +545,7 @@ int local_open_client_rx(FAR struct local_conn_s *client, bool nonblock); * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_client_tx(FAR struct local_conn_s *client, bool nonblock); -#endif /**************************************************************************** * Name: local_open_server_rx @@ -563,9 +555,7 @@ int local_open_client_tx(FAR struct local_conn_s *client, bool nonblock); * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_server_rx(FAR struct local_conn_s *server, bool nonblock); -#endif /**************************************************************************** * Name: local_open_server_tx @@ -575,9 +565,7 @@ int local_open_server_rx(FAR struct local_conn_s *server, bool nonblock); * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_server_tx(FAR struct local_conn_s *server, bool nonblock); -#endif /**************************************************************************** * Name: local_open_receiver @@ -657,6 +645,19 @@ int local_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds); int32_t local_generate_instance_id(void); +/**************************************************************************** + * Name: local_set_pollthreshold + * + * Description: + * Set the local pollin and pollout threshold: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOCAL_DGRAM +int local_set_pollthreshold(FAR struct local_conn_s *conn, + unsigned long threshold); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/net/local/local_fifo.c b/net/local/local_fifo.c index c9849d25e98..4ff2caff037 100644 --- a/net/local/local_fifo.c +++ b/net/local/local_fifo.c @@ -96,13 +96,11 @@ static void local_format_name(FAR const char *inpath, FAR char *outpath, * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM static void local_cs_name(FAR struct local_conn_s *conn, FAR char *path) { local_format_name(conn->lc_path, path, LOCAL_CS_SUFFIX, conn->lc_instance_id); } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_sc_name @@ -112,13 +110,11 @@ static void local_cs_name(FAR struct local_conn_s *conn, FAR char *path) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM static void local_sc_name(FAR struct local_conn_s *conn, FAR char *path) { local_format_name(conn->lc_path, path, LOCAL_SC_SUFFIX, conn->lc_instance_id); } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_hd_name @@ -203,7 +199,6 @@ static int local_create_fifo(FAR const char *path) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM /* Currently not used by datagram code */ static int local_release_fifo(FAR const char *path) { int ret; @@ -230,7 +225,6 @@ static int local_release_fifo(FAR const char *path) return OK; } -#endif /**************************************************************************** * Name: local_rx_open @@ -394,6 +388,32 @@ static int local_set_polloutthreshold(FAR struct file *filep, * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: local_set_pollthreshold + * + * Description: + * Set the local pollin and pollout threshold: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOCAL_DGRAM +int local_set_pollthreshold(FAR struct local_conn_s *conn, + unsigned long threshold) +{ + int ret; + + /* Set the buffer poll threshold */ + + ret = local_set_pollinthreshold(&conn->lc_infile, threshold); + if (ret > 0) + { + ret = local_set_polloutthreshold(&conn->lc_outfile, threshold); + } + + return ret; +} +#endif /* CONFIG_NET_LOCAL_DGRAM */ + /**************************************************************************** * Name: local_create_fifos * @@ -402,7 +422,6 @@ static int local_set_polloutthreshold(FAR struct file *filep, * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_create_fifos(FAR struct local_conn_s *conn) { char path[LOCAL_FULLPATH_LEN]; @@ -422,7 +441,6 @@ int local_create_fifos(FAR struct local_conn_s *conn) return ret; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_create_halfduplex @@ -453,7 +471,6 @@ int local_create_halfduplex(FAR struct local_conn_s *conn, * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_release_fifos(FAR struct local_conn_s *conn) { char path[LOCAL_FULLPATH_LEN]; @@ -474,7 +491,6 @@ int local_release_fifos(FAR struct local_conn_s *conn) return ret1 < 0 ? ret1 : ret2; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_release_halfduplex @@ -524,7 +540,6 @@ int local_release_halfduplex(FAR struct local_conn_s *conn) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_client_rx(FAR struct local_conn_s *client, bool nonblock) { char path[LOCAL_FULLPATH_LEN]; @@ -546,7 +561,6 @@ int local_open_client_rx(FAR struct local_conn_s *client, bool nonblock) return ret; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_open_client_tx @@ -556,7 +570,6 @@ int local_open_client_rx(FAR struct local_conn_s *client, bool nonblock) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_client_tx(FAR struct local_conn_s *client, bool nonblock) { char path[LOCAL_FULLPATH_LEN]; @@ -578,7 +591,6 @@ int local_open_client_tx(FAR struct local_conn_s *client, bool nonblock) return ret; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_open_server_rx @@ -588,7 +600,6 @@ int local_open_client_tx(FAR struct local_conn_s *client, bool nonblock) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_server_rx(FAR struct local_conn_s *server, bool nonblock) { char path[LOCAL_FULLPATH_LEN]; @@ -610,7 +621,6 @@ int local_open_server_rx(FAR struct local_conn_s *server, bool nonblock) return ret; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_open_server_tx @@ -620,7 +630,6 @@ int local_open_server_rx(FAR struct local_conn_s *server, bool nonblock) * ****************************************************************************/ -#ifdef CONFIG_NET_LOCAL_STREAM int local_open_server_tx(FAR struct local_conn_s *server, bool nonblock) { char path[LOCAL_FULLPATH_LEN]; @@ -642,7 +651,6 @@ int local_open_server_tx(FAR struct local_conn_s *server, bool nonblock) return ret; } -#endif /* CONFIG_NET_LOCAL_STREAM */ /**************************************************************************** * Name: local_open_receiver diff --git a/net/local/local_recvmsg.c b/net/local/local_recvmsg.c index e106cc86a01..c8b318361d5 100644 --- a/net/local/local_recvmsg.c +++ b/net/local/local_recvmsg.c @@ -277,6 +277,7 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, FAR struct local_conn_s *conn = psock->s_conn; uint16_t pktlen; size_t readlen; + bool bclose = false; int ret; /* We keep packet sizes in a uint16_t, so there is a upper limit to the @@ -287,7 +288,8 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Verify that this is a bound, un-connected peer socket */ - if (conn->lc_state != LOCAL_STATE_BOUND) + if (conn->lc_state != LOCAL_STATE_BOUND && + conn->lc_state != LOCAL_STATE_CONNECTED) { /* Either not bound to address or it is connected */ @@ -295,29 +297,30 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, return -EISCONN; } - /* The incoming FIFO should not be open */ - - DEBUGASSERT(conn->lc_infile.f_inode == NULL); - - /* Make sure that half duplex FIFO has been created */ - - ret = local_create_halfduplex(conn, conn->lc_path); - if (ret < 0) + if (conn->lc_infile.f_inode == NULL) { - nerr("ERROR: Failed to create FIFO for %s: %d\n", - conn->lc_path, ret); - return ret; - } + bclose = true; - /* Open the receiving side of the transfer */ + /* Make sure that half duplex FIFO has been created */ - ret = local_open_receiver(conn, _SS_ISNONBLOCK(conn->lc_conn.s_flags) || - (flags & MSG_DONTWAIT) != 0); - if (ret < 0) - { - nerr("ERROR: Failed to open FIFO for %s: %d\n", - conn->lc_path, ret); - goto errout_with_halfduplex; + ret = local_create_halfduplex(conn, conn->lc_path); + if (ret < 0) + { + nerr("ERROR: Failed to create FIFO for %s: %d\n", + conn->lc_path, ret); + return ret; + } + + /* Open the receiving side of the transfer */ + + ret = local_open_receiver(conn, (flags & MSG_DONTWAIT) != 0 || + _SS_ISNONBLOCK(conn->lc_conn.s_flags)); + if (ret < 0) + { + nerr("ERROR: Failed to open FIFO for %s: %d\n", + conn->lc_path, ret); + goto errout_with_halfduplex; + } } /* Sync to the start of the next packet in the stream and get the size of @@ -381,15 +384,6 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, while (remaining > 0); } - /* Now we can close the read-only file descriptor */ - - file_close(&conn->lc_infile); - conn->lc_infile.f_inode = NULL; - - /* Release our reference to the half duplex FIFO */ - - local_release_halfduplex(conn); - /* Return the address family */ if (from) @@ -401,21 +395,25 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, } } - return readlen; - errout_with_infd: /* Close the read-only file descriptor */ - file_close(&conn->lc_infile); - conn->lc_infile.f_inode = NULL; + if (bclose) + { + /* Now we can close the read-only file descriptor */ + + file_close(&conn->lc_infile); + conn->lc_infile.f_inode = NULL; errout_with_halfduplex: - /* Release our reference to the half duplex FIFO */ + /* Release our reference to the half duplex FIFO */ - local_release_halfduplex(conn); - return ret; + local_release_halfduplex(conn); + } + + return ret < 0 ? ret : readlen; } #endif /* CONFIG_NET_LOCAL_STREAM */ diff --git a/net/local/local_release.c b/net/local/local_release.c index ca1717ddbf6..d269945d619 100644 --- a/net/local/local_release.c +++ b/net/local/local_release.c @@ -66,20 +66,9 @@ int local_release(FAR struct local_conn_s *conn) DEBUGASSERT(conn->lc_state != LOCAL_STATE_ACCEPT); - /* If the socket is connected (SOCK_STREAM client), then disconnect it */ - - if (conn->lc_state == LOCAL_STATE_CONNECTED || - conn->lc_state == LOCAL_STATE_CONNECTING || - conn->lc_state == LOCAL_STATE_DISCONNECTED) - { - DEBUGASSERT(conn->lc_proto == SOCK_STREAM); - - /* Just free the connection structure */ - } - /* Is the socket is listening socket (SOCK_STREAM server) */ - else if (conn->lc_state == LOCAL_STATE_LISTENING) + if (conn->lc_state == LOCAL_STATE_LISTENING) { FAR struct local_conn_s *client; FAR dq_entry_t *waiter; diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c index 490d478718f..30717efeb0a 100644 --- a/net/local/local_sendmsg.c +++ b/net/local/local_sendmsg.c @@ -170,6 +170,10 @@ static ssize_t local_send(FAR struct socket *psock, { #ifdef CONFIG_NET_LOCAL_STREAM case SOCK_STREAM: +#endif /* CONFIG_NET_LOCAL_STREAM */ +#ifdef CONFIG_NET_LOCAL_DGRAM + case SOCK_DGRAM: +#endif /* CONFIG_NET_LOCAL_DGRAM */ { FAR struct local_conn_s *peer; @@ -204,24 +208,11 @@ static ssize_t local_send(FAR struct socket *psock, return ret; } - ret = local_send_packet(&peer->lc_outfile, buf, len, false); + ret = local_send_packet(&peer->lc_outfile, buf, len, + psock->s_type == SOCK_DGRAM); nxmutex_unlock(&peer->lc_sendlock); } break; -#endif /* CONFIG_NET_LOCAL_STREAM */ - -#ifdef CONFIG_NET_LOCAL_DGRAM - case SOCK_DGRAM: - { - /* Local UDP packet send */ - - /* #warning Missing logic */ - - ret = -ENOSYS; - } - break; -#endif /* CONFIG_NET_LOCAL_DGRAM */ - default: { /* EDESTADDRREQ. Signifies that the socket is not connection-mode diff --git a/net/local/local_sockif.c b/net/local/local_sockif.c index 4d44db23ce1..2b07921991e 100644 --- a/net/local/local_sockif.c +++ b/net/local/local_sockif.c @@ -811,12 +811,9 @@ static int local_ioctl(FAR struct socket *psock, int cmd, unsigned long arg) static int local_socketpair(FAR struct socket *psocks[2]) { -#if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_LOCAL_DGRAM) FAR struct local_conn_s *conns[2]; -#ifdef CONFIG_NET_LOCAL_STREAM bool nonblock; int ret; -#endif /* CONFIG_NET_LOCAL_STREAM */ int i; for (i = 0; i < 2; i++) @@ -830,18 +827,12 @@ static int local_socketpair(FAR struct socket *psocks[2]) conns[i]->lc_state = LOCAL_STATE_BOUND; } -#ifdef CONFIG_NET_LOCAL_DGRAM -#ifdef CONFIG_NET_LOCAL_STREAM - if (psocks[0]->s_type == SOCK_DGRAM) -#endif /* CONFIG_NET_LOCAL_STREAM */ - { - return OK; - } -#endif /* CONFIG_NET_LOCAL_DGRAM */ - -#ifdef CONFIG_NET_LOCAL_STREAM conns[0]->lc_instance_id = conns[1]->lc_instance_id +#ifdef CONFIG_NET_LOCAL_STREAM = local_generate_instance_id(); +#else + = -1; +#endif /* Create the FIFOs needed for the connection */ @@ -887,15 +878,22 @@ static int local_socketpair(FAR struct socket *psocks[2]) conns[0]->lc_state = conns[1]->lc_state = LOCAL_STATE_CONNECTED; + +#ifdef CONFIG_NET_LOCAL_DGRAM + if (psocks[0]->s_type == SOCK_DGRAM) + { + for (i = 0; i < 2; i++) + { + ret = local_set_pollthreshold(conns[i], sizeof(uint16_t)); + } + } +#endif + return OK; errout: local_release_fifos(conns[0]); return ret; -#endif /* CONFIG_NET_LOCAL_STREAM */ -#else - return -EOPNOTSUPP; -#endif /* CONFIG_NET_LOCAL_STREAM || CONFIG_NET_LOCAL_DGRAM */ } /****************************************************************************