1
0
Fork 0
forked from nuttx/nuttx-update

net/local: Support the abstract path

https://man7.org/linux/man-pages/man7/unix.7.html

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2022-12-18 15:18:56 +08:00 committed by Petro Karashchenko
parent 6b36ba0b6e
commit 4d2794250f
3 changed files with 53 additions and 44 deletions

View file

@ -66,6 +66,7 @@ int psock_local_bind(FAR struct socket *psock,
/* Save the address family */
conn->lc_proto = psock->s_type;
conn->lc_instance_id = -1;
/* Now determine the type of the Unix domain socket by comparing the size
* of the address description.
@ -75,8 +76,11 @@ int psock_local_bind(FAR struct socket *psock,
{
/* Zero-length sun_path... This is an abstract Unix domain socket */
conn->lc_type = LOCAL_TYPE_ABSTRACT;
conn->lc_path[0] = '\0';
conn->lc_type = LOCAL_TYPE_ABSTRACT;
/* Copy the path into the connection structure */
strlcpy(conn->lc_path, &unaddr->sun_path[1], sizeof(conn->lc_path));
}
else
{
@ -87,7 +91,6 @@ int psock_local_bind(FAR struct socket *psock,
/* Copy the path into the connection structure */
strlcpy(conn->lc_path, unaddr->sun_path, sizeof(conn->lc_path));
conn->lc_instance_id = -1;
}
conn->lc_state = LOCAL_STATE_BOUND;

View file

@ -238,7 +238,9 @@ int psock_local_connect(FAR struct socket *psock,
{
FAR struct local_conn_s *client;
FAR struct sockaddr_un *unaddr = (FAR struct sockaddr_un *)addr;
FAR const char *unpath = unaddr->sun_path;
FAR struct local_conn_s *conn = NULL;
uint8_t type = LOCAL_TYPE_PATHNAME;
DEBUGASSERT(psock && psock->s_conn);
client = (FAR struct local_conn_s *)psock->s_conn;
@ -249,6 +251,12 @@ int psock_local_connect(FAR struct socket *psock,
return -EISCONN;
}
if (unpath[0] == '\0')
{
type = LOCAL_TYPE_ABSTRACT;
unpath++;
}
/* Find the matching server connection */
net_lock();
@ -269,51 +277,41 @@ int psock_local_connect(FAR struct socket *psock,
break;
case LOCAL_TYPE_ABSTRACT: /* lc_path is length zero */
{
#warning Missing logic
net_unlock();
return OK;
}
break;
case LOCAL_TYPE_PATHNAME: /* lc_path holds a null terminated string */
{
/* Anything in the listener list should be a stream socket in the
* listening state
*/
if (conn->lc_state == LOCAL_STATE_LISTENING &&
conn->lc_proto == SOCK_STREAM &&
strncmp(conn->lc_path, unaddr->sun_path, UNIX_PATH_MAX - 1)
== 0)
{
int ret = OK;
/* Anything in the listener list should be a stream socket in the
* listening state
*/
/* Bind the address and protocol */
if (conn->lc_state == LOCAL_STATE_LISTENING &&
conn->lc_type == type && conn->lc_proto == SOCK_STREAM &&
strncmp(conn->lc_path, unpath, UNIX_PATH_MAX - 1) == 0)
{
int ret = OK;
client->lc_type = conn->lc_type;
client->lc_proto = conn->lc_proto;
strlcpy(client->lc_path, unaddr->sun_path,
sizeof(client->lc_path));
client->lc_instance_id = local_generate_instance_id();
/* Bind the address and protocol */
/* The client is now bound to an address */
client->lc_type = conn->lc_type;
client->lc_proto = conn->lc_proto;
strlcpy(client->lc_path, unpath, sizeof(client->lc_path));
client->lc_instance_id = local_generate_instance_id();
client->lc_state = LOCAL_STATE_BOUND;
/* The client is now bound to an address */
/* We have to do more for the SOCK_STREAM family */
client->lc_state = LOCAL_STATE_BOUND;
if (conn->lc_proto == SOCK_STREAM)
{
ret =
local_stream_connect(client, conn,
_SS_ISNONBLOCK(client->lc_conn.s_flags));
}
/* We have to do more for the SOCK_STREAM family */
if (conn->lc_proto == SOCK_STREAM)
{
ret = local_stream_connect(client, conn,
_SS_ISNONBLOCK(client->lc_conn.s_flags));
}
net_unlock();
return ret;
}
net_unlock();
return ret;
}
}
break;
default: /* Bad, memory must be corrupted */

View file

@ -379,15 +379,16 @@ static int local_getsockname(FAR struct socket *psock,
*addrlen = sizeof(sa_family_t);
}
else /* conn->lctype = LOCAL_TYPE_PATHNAME */
else /* conn->lc_type = LOCAL_TYPE_PATHNAME */
{
/* Get the full length of the socket name (incl. null terminator) */
int namelen = strlen(conn->lc_path) + 1;
size_t namelen = strlen(conn->lc_path) + 1 +
(conn->lc_type == LOCAL_TYPE_ABSTRACT);
/* Get the available length in the user-provided buffer. */
int pathlen = *addrlen - sizeof(sa_family_t);
size_t pathlen = *addrlen - sizeof(sa_family_t);
/* Clip the socket name size so that if fits in the user buffer */
@ -398,8 +399,15 @@ static int local_getsockname(FAR struct socket *psock,
/* Copy the path into the user address structure */
strlcpy(unaddr->sun_path, conn->lc_path, namelen);
unaddr->sun_path[pathlen - 1] = '\0';
if (conn->lc_type == LOCAL_TYPE_ABSTRACT)
{
unaddr->sun_path[0] = '\0';
strlcpy(&unaddr->sun_path[1], conn->lc_path, namelen - 1);
}
else
{
strlcpy(unaddr->sun_path, conn->lc_path, namelen);
}
*addrlen = sizeof(sa_family_t) + namelen;
}