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 <liqinhui@xiaomi.com>
This commit is contained in:
liqinhui 2023-06-27 16:28:09 +08:00 committed by Xiang Xiao
parent 92040a2bdf
commit a7a47621fa
6 changed files with 96 additions and 111 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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,9 +297,9 @@ 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);
if (conn->lc_infile.f_inode == NULL)
{
bclose = true;
/* Make sure that half duplex FIFO has been created */
@ -311,14 +313,15 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
/* Open the receiving side of the transfer */
ret = local_open_receiver(conn, _SS_ISNONBLOCK(conn->lc_conn.s_flags) ||
(flags & MSG_DONTWAIT) != 0);
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
* the next packet.
@ -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,12 +395,14 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
}
}
return readlen;
errout_with_infd:
/* Close the read-only file descriptor */
if (bclose)
{
/* Now we can close the read-only file descriptor */
file_close(&conn->lc_infile);
conn->lc_infile.f_inode = NULL;
@ -415,7 +411,9 @@ errout_with_halfduplex:
/* Release our reference to the half duplex FIFO */
local_release_halfduplex(conn);
return ret;
}
return ret < 0 ? ret : readlen;
}
#endif /* CONFIG_NET_LOCAL_STREAM */

View File

@ -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;

View File

@ -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

View File

@ -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 */
}
/****************************************************************************