mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 10:46:28 +08:00
net/local/local_sockif.c:add local_getpeername function implementation
this testcast
TEST_IMPL(udp_send_unix) {
/* Test that "uv_udp_send()" supports sending over
a "sockaddr_un" address. */
struct sockaddr_un addr;
uv_udp_t handle;
uv_udp_send_t req;
uv_loop_t* loop;
uv_buf_t buf = uv_buf_init("PING", 4);
int fd;
int r;
loop = uv_default_loop();
memset(&addr, 0, sizeof addr);
addr.sun_family = AF_UNIX;
ASSERT(strlen(TEST_PIPENAME) < sizeof(addr.sun_path));
memcpy(addr.sun_path, TEST_PIPENAME, strlen(TEST_PIPENAME));
fd = socket(AF_UNIX, SOCK_STREAM, 0);
ASSERT(fd >= 0);
unlink(TEST_PIPENAME);
ASSERT(0 == bind(fd, (const struct sockaddr*)&addr, sizeof addr));
ASSERT(0 == listen(fd, 1));
r = uv_udp_init(loop, &handle);
ASSERT(r == 0);
r = uv_udp_open(&handle, fd);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
r = uv_udp_send(&req,
&handle,
&buf,
1,
(const struct sockaddr*) &addr,
NULL);
ASSERT(r == 0);
uv_close((uv_handle_t*)&handle, NULL);
uv_run(loop, UV_RUN_DEFAULT);
close(fd);
unlink(TEST_PIPENAME);
MAKE_VALGRIND_HAPPY();
return 0;
}
Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
+1
-1
@@ -122,9 +122,9 @@ struct local_conn_s
|
||||
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_SCM
|
||||
FAR struct local_conn_s *
|
||||
lc_peer; /* Peer connection instance */
|
||||
#ifdef CONFIG_NET_LOCAL_SCM
|
||||
uint16_t lc_cfpcount; /* Control file pointer counter */
|
||||
FAR struct file *
|
||||
lc_cfps[LOCAL_NCONTROLFDS]; /* Socket message control filep */
|
||||
|
||||
@@ -169,10 +169,8 @@ int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
conn->lc_type = LOCAL_TYPE_PATHNAME;
|
||||
conn->lc_state = LOCAL_STATE_CONNECTED;
|
||||
conn->lc_psock = psock;
|
||||
#ifdef CONFIG_NET_LOCAL_SCM
|
||||
conn->lc_peer = client;
|
||||
client->lc_peer = conn;
|
||||
#endif /* CONFIG_NET_LOCAL_SCM */
|
||||
|
||||
strlcpy(conn->lc_path, client->lc_path, sizeof(conn->lc_path));
|
||||
conn->lc_instance_id = client->lc_instance_id;
|
||||
|
||||
@@ -168,13 +168,11 @@ void local_free(FAR struct local_conn_s *conn)
|
||||
net_lock();
|
||||
dq_rem(&conn->lc_conn.node, &g_local_connections);
|
||||
|
||||
#ifdef CONFIG_NET_LOCAL_SCM
|
||||
if (local_peerconn(conn) && conn->lc_peer)
|
||||
{
|
||||
conn->lc_peer->lc_peer = NULL;
|
||||
conn->lc_peer = NULL;
|
||||
}
|
||||
#endif /* CONFIG_NET_LOCAL_SCM */
|
||||
|
||||
net_unlock();
|
||||
|
||||
|
||||
@@ -463,7 +463,82 @@ static int local_getpeername(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
return local_getsockname(psock, addr, addrlen);
|
||||
FAR struct sockaddr_un *unaddr = (FAR struct sockaddr_un *)addr;
|
||||
FAR struct local_conn_s *conn;
|
||||
FAR struct local_conn_s *peer;
|
||||
|
||||
DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
|
||||
unaddr != NULL && addrlen != NULL);
|
||||
|
||||
if (*addrlen < sizeof(sa_family_t))
|
||||
{
|
||||
/* This is apparently not an error */
|
||||
|
||||
*addrlen = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Verify that the socket has been connected */
|
||||
|
||||
conn = psock->s_conn;
|
||||
|
||||
if (conn->lc_state != LOCAL_STATE_CONNECTED)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
peer = conn->lc_peer;
|
||||
|
||||
/* Save the address family */
|
||||
|
||||
unaddr->sun_family = AF_LOCAL;
|
||||
if (*addrlen > sizeof(sa_family_t))
|
||||
{
|
||||
/* Now copy the address description. */
|
||||
|
||||
if (peer->lc_type == LOCAL_TYPE_UNNAMED)
|
||||
{
|
||||
/* Zero-length sun_path... This is an abstract Unix domain socket */
|
||||
|
||||
*addrlen = sizeof(sa_family_t);
|
||||
}
|
||||
else /* conn->lc_type = LOCAL_TYPE_PATHNAME */
|
||||
{
|
||||
/* Get the full length of the socket name (incl. null terminator) */
|
||||
|
||||
size_t namelen = strlen(peer->lc_path) + 1 +
|
||||
(peer->lc_type == LOCAL_TYPE_ABSTRACT);
|
||||
|
||||
/* Get the available length in the user-provided buffer. */
|
||||
|
||||
size_t pathlen = *addrlen - sizeof(sa_family_t);
|
||||
|
||||
/* Clip the socket name size so that if fits in the user buffer */
|
||||
|
||||
if (pathlen < namelen)
|
||||
{
|
||||
namelen = pathlen;
|
||||
}
|
||||
|
||||
/* Copy the path into the user address structure */
|
||||
|
||||
if (peer->lc_type == LOCAL_TYPE_ABSTRACT)
|
||||
{
|
||||
unaddr->sun_path[0] = '\0';
|
||||
strlcpy(&unaddr->sun_path[1],
|
||||
peer->lc_path, namelen - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy(unaddr->sun_path,
|
||||
peer->lc_path, namelen);
|
||||
}
|
||||
|
||||
*addrlen = sizeof(sa_family_t) + namelen;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_SOCKOPTS
|
||||
|
||||
Reference in New Issue
Block a user