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:
parent
6b36ba0b6e
commit
4d2794250f
3 changed files with 53 additions and 44 deletions
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue