diff --git a/net/local/local.h b/net/local/local.h index 1733d1ffcbb..6b57249f842 100644 --- a/net/local/local.h +++ b/net/local/local.h @@ -281,6 +281,21 @@ void local_subref(FAR struct local_conn_s *conn); FAR struct local_conn_s *local_nextconn(FAR struct local_conn_s *conn); +/**************************************************************************** + * Name: local_findconn + * + * Description: + * Traverse the connections list to find the server + * + * Assumptions: + * This function must be called with the network locked. + * + ****************************************************************************/ + +FAR struct local_conn_s * +local_findconn(FAR const struct local_conn_s *conn, + FAR const struct sockaddr_un *unaddr); + /**************************************************************************** * Name: local_peerconn * diff --git a/net/local/local_bind.c b/net/local/local_bind.c index a2d64895806..627b6eee5ca 100644 --- a/net/local/local_bind.c +++ b/net/local/local_bind.c @@ -51,6 +51,7 @@ int psock_local_bind(FAR struct socket *psock, FAR struct local_conn_s *conn = psock->s_conn; FAR const struct sockaddr_un *unaddr = (FAR const struct sockaddr_un *)addr; + int index; DEBUGASSERT(unaddr->sun_family == AF_LOCAL); @@ -59,6 +60,15 @@ int psock_local_bind(FAR struct socket *psock, return -EINVAL; } + conn = psock->s_conn; + + /* Check if local address is already in use */ + + if (local_findconn(conn, unaddr) != NULL) + { + return -EADDRINUSE; + } + /* Save the address family */ conn->lc_instance_id = -1; @@ -72,22 +82,18 @@ 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; - - /* Copy the path into the connection structure */ - - strlcpy(conn->lc_path, &unaddr->sun_path[1], sizeof(conn->lc_path)); + index = 1; } else { /* This is an normal, pathname Unix domain socket */ conn->lc_type = LOCAL_TYPE_PATHNAME; - - /* Copy the path into the connection structure */ - - strlcpy(conn->lc_path, unaddr->sun_path, sizeof(conn->lc_path)); + index = 0; } + strlcpy(conn->lc_path, &unaddr->sun_path[index], sizeof(conn->lc_path)); + conn->lc_state = LOCAL_STATE_BOUND; return OK; } diff --git a/net/local/local_conn.c b/net/local/local_conn.c index 55e82899ff6..acb6f80fe03 100644 --- a/net/local/local_conn.c +++ b/net/local/local_conn.c @@ -68,6 +68,38 @@ FAR struct local_conn_s *local_nextconn(FAR struct local_conn_s *conn) return (FAR struct local_conn_s *)conn->lc_conn.node.flink; } +/**************************************************************************** + * Name: local_findconn + * + * Description: + * Traverse the connections list to find the local connection + * + * Assumptions: + * This function must be called with the network locked. + * + ****************************************************************************/ + +FAR struct local_conn_s * +local_findconn(FAR const struct local_conn_s *local_conn, + FAR const struct sockaddr_un *unaddr) +{ + FAR struct local_conn_s *conn = NULL; + + int index = unaddr->sun_path[0] == '\0' ? 1 : 0; + + while ((conn = local_nextconn(conn)) != NULL) + { + if (local_conn->lc_proto == conn->lc_proto && + strncmp(conn->lc_path, &unaddr->sun_path[index], + UNIX_PATH_MAX - 1) == 0) + { + return conn; + } + } + + return NULL; +} + /**************************************************************************** * Name: local_peerconn * diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c index 0ae6c5719fb..81dad3e576a 100644 --- a/net/local/local_sendmsg.c +++ b/net/local/local_sendmsg.c @@ -262,7 +262,7 @@ static ssize_t local_sendto(FAR struct socket *psock, { #ifdef CONFIG_NET_LOCAL_DGRAM FAR struct local_conn_s *conn = psock->s_conn; - FAR struct sockaddr_un *unaddr = (FAR struct sockaddr_un *)to; + FAR const struct sockaddr_un *unaddr = (FAR const struct sockaddr_un *)to; ssize_t ret; /* Verify that a valid address has been provided */ @@ -296,6 +296,12 @@ static ssize_t local_sendto(FAR struct socket *psock, return -EISCONN; } + if (local_findconn(conn, unaddr) == NULL) + { + nerr("ERROR: No such file or directory\n"); + return -ENOENT; + } + /* The outgoing FIFO should not be open */ DEBUGASSERT(conn->lc_outfile.f_inode == NULL);