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:
wangchen
2023-08-03 11:28:28 +08:00
committed by Xiang Xiao
parent f324d1d8dd
commit d528d2c410
4 changed files with 77 additions and 6 deletions
+1 -1
View File
@@ -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 */
-2
View File
@@ -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;
-2
View File
@@ -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();
+76 -1
View File
@@ -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