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:
parent
3c1af2feed
commit
0f5c35260b
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user