Local sockets: Local stream sockets had problem of double releasing pipes (both server and client attempt release), which causes wrong pipe pair being closed in multi-client case. Solve by adding per connection instance ID to pipe names. From Jussi Kivilinna (2015-05-12).

This commit is contained in:
Gregory Nutt 2015-05-12 07:47:32 -06:00
parent 3c1af2feed
commit 0f5c35260b
5 changed files with 47 additions and 4 deletions

View File

@ -143,6 +143,8 @@ struct local_conn_s
int16_t lc_infd; /* File descriptor of read-only FIFO (peers) */
int16_t lc_outfd; /* File descriptor of write-only FIFO (peers) */
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_STREAM
/* SOCK_STREAM fields common to both client and server */

View File

@ -170,6 +170,7 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
strncpy(conn->lc_path, client->lc_path, UNIX_PATH_MAX-1);
conn->lc_path[UNIX_PATH_MAX-1] = '\0';
conn->lc_instance_id = client->lc_instance_id;
/* Open the server-side write-only FIFO. This should not
* block.

View File

@ -109,6 +109,7 @@ int psock_local_bind(FAR struct socket *psock,
(void)strncpy(conn->lc_path, unaddr->sun_path, UNIX_PATH_MAX-1);
conn->lc_path[UNIX_PATH_MAX-1] = '\0';
conn->lc_instance_id = -1;
}
}

View File

@ -59,6 +59,26 @@
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: local_generate_instance_id
****************************************************************************/
static int32_t local_generate_instance_id(void)
{
static int32_t g_next_instance_id = 0;
int32_t id;
/* Called from local_connect with net_lock held. */
id = g_next_instance_id++;
if (g_next_instance_id < 0)
{
g_next_instance_id = 0;
}
return id;
}
/****************************************************************************
* Name: _local_semtake() and _local_semgive()
*
@ -286,6 +306,7 @@ int psock_local_connect(FAR struct socket *psock,
client->lc_proto = conn->lc_proto;
strncpy(client->lc_path, unaddr->sun_path, UNIX_PATH_MAX-1);
client->lc_path[UNIX_PATH_MAX-1] = '\0';
client->lc_instance_id = local_generate_instance_id();
/* The client is now bound to an address */

View File

@ -80,8 +80,17 @@
static inline void local_cs_name(FAR struct local_conn_s *conn,
FAR char *path)
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_CS_SUFFIX,
conn->lc_path);
if (conn->lc_instance_id < 0)
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_CS_SUFFIX,
conn->lc_path);
}
else
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_CS_SUFFIX "%x",
conn->lc_path, conn->lc_instance_id);
}
path[LOCAL_FULLPATH_LEN-1] = '\0';
}
#endif /* CONFIG_NET_LOCAL_STREAM */
@ -98,8 +107,17 @@ static inline void local_cs_name(FAR struct local_conn_s *conn,
static inline void local_sc_name(FAR struct local_conn_s *conn,
FAR char *path)
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_SC_SUFFIX,
conn->lc_path);
if (conn->lc_instance_id < 0)
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_SC_SUFFIX,
conn->lc_path);
}
else
{
(void)snprintf(path, LOCAL_FULLPATH_LEN-1, "%s" LOCAL_SC_SUFFIX "%x",
conn->lc_path, conn->lc_instance_id);
}
path[LOCAL_FULLPATH_LEN-1] = '\0';
}
#endif /* CONFIG_NET_LOCAL_STREAM */