sock: Add a function to check if a socket is connected
This is useful for detecting sockets that have been disconnected by the other end without reading data. Change-Id: Ieb6529984d282d48373766d9f5555cf11720f19b Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470513 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
85d9f0a9ab
commit
a0889ece60
@ -195,6 +195,15 @@ bool spdk_sock_is_ipv6(struct spdk_sock *sock);
|
|||||||
*/
|
*/
|
||||||
bool spdk_sock_is_ipv4(struct spdk_sock *sock);
|
bool spdk_sock_is_ipv4(struct spdk_sock *sock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the socket is currently connected.
|
||||||
|
*
|
||||||
|
* \param sock Socket to check
|
||||||
|
*
|
||||||
|
* \return true if the socket is connected or false otherwise.
|
||||||
|
*/
|
||||||
|
bool spdk_sock_is_connected(struct spdk_sock *sock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function for spdk_sock_group_add_sock().
|
* Callback function for spdk_sock_group_add_sock().
|
||||||
*
|
*
|
||||||
|
@ -86,6 +86,7 @@ struct spdk_net_impl {
|
|||||||
|
|
||||||
bool (*is_ipv6)(struct spdk_sock *sock);
|
bool (*is_ipv6)(struct spdk_sock *sock);
|
||||||
bool (*is_ipv4)(struct spdk_sock *sock);
|
bool (*is_ipv4)(struct spdk_sock *sock);
|
||||||
|
bool (*is_connected)(struct spdk_sock *sock);
|
||||||
|
|
||||||
int (*get_placement_id)(struct spdk_sock *sock, int *placement_id);
|
int (*get_placement_id)(struct spdk_sock *sock, int *placement_id);
|
||||||
struct spdk_sock_group_impl *(*group_impl_create)(void);
|
struct spdk_sock_group_impl *(*group_impl_create)(void);
|
||||||
|
@ -308,6 +308,12 @@ spdk_sock_is_ipv4(struct spdk_sock *sock)
|
|||||||
return sock->net_impl->is_ipv4(sock);
|
return sock->net_impl->is_ipv4(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
spdk_sock_is_connected(struct spdk_sock *sock)
|
||||||
|
{
|
||||||
|
return sock->net_impl->is_connected(sock);
|
||||||
|
}
|
||||||
|
|
||||||
struct spdk_sock_group *
|
struct spdk_sock_group *
|
||||||
spdk_sock_group_create(void *ctx)
|
spdk_sock_group_create(void *ctx)
|
||||||
{
|
{
|
||||||
|
@ -529,6 +529,29 @@ spdk_posix_sock_is_ipv4(struct spdk_sock *_sock)
|
|||||||
return (sa.ss_family == AF_INET);
|
return (sa.ss_family == AF_INET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
spdk_posix_sock_is_connected(struct spdk_sock *_sock)
|
||||||
|
{
|
||||||
|
struct spdk_posix_sock *sock = __posix_sock(_sock);
|
||||||
|
uint8_t byte;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = recv(sock->fd, &byte, 1, MSG_PEEK);
|
||||||
|
if (rc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_posix_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
spdk_posix_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
||||||
{
|
{
|
||||||
@ -686,6 +709,7 @@ static struct spdk_net_impl g_posix_net_impl = {
|
|||||||
.set_priority = spdk_posix_sock_set_priority,
|
.set_priority = spdk_posix_sock_set_priority,
|
||||||
.is_ipv6 = spdk_posix_sock_is_ipv6,
|
.is_ipv6 = spdk_posix_sock_is_ipv6,
|
||||||
.is_ipv4 = spdk_posix_sock_is_ipv4,
|
.is_ipv4 = spdk_posix_sock_is_ipv4,
|
||||||
|
.is_connected = spdk_posix_sock_is_connected,
|
||||||
.get_placement_id = spdk_posix_sock_get_placement_id,
|
.get_placement_id = spdk_posix_sock_get_placement_id,
|
||||||
.group_impl_create = spdk_posix_sock_group_impl_create,
|
.group_impl_create = spdk_posix_sock_group_impl_create,
|
||||||
.group_impl_add_sock = spdk_posix_sock_group_impl_add_sock,
|
.group_impl_add_sock = spdk_posix_sock_group_impl_add_sock,
|
||||||
|
@ -1006,6 +1006,14 @@ spdk_vpp_sock_is_ipv4(struct spdk_sock *_sock)
|
|||||||
return __vpp_session(_sock)->app_session.transport.is_ip4;
|
return __vpp_session(_sock)->app_session.transport.is_ip4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
spdk_vpp_sock_is_connected(struct spdk_sock *_sock)
|
||||||
|
{
|
||||||
|
assert(g_svm.vpp_initialized);
|
||||||
|
|
||||||
|
return (__vpp_session(_sock)->app_session.session_state == VPP_SESSION_STATE_READY);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_vpp_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
spdk_vpp_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
||||||
{
|
{
|
||||||
@ -1440,6 +1448,7 @@ static struct spdk_net_impl g_vpp_net_impl = {
|
|||||||
.set_priority = spdk_vpp_sock_set_priority,
|
.set_priority = spdk_vpp_sock_set_priority,
|
||||||
.is_ipv6 = spdk_vpp_sock_is_ipv6,
|
.is_ipv6 = spdk_vpp_sock_is_ipv6,
|
||||||
.is_ipv4 = spdk_vpp_sock_is_ipv4,
|
.is_ipv4 = spdk_vpp_sock_is_ipv4,
|
||||||
|
.is_connected = spdk_vpp_sock_is_connected,
|
||||||
.get_placement_id = spdk_vpp_sock_get_placement_id,
|
.get_placement_id = spdk_vpp_sock_get_placement_id,
|
||||||
.group_impl_create = spdk_vpp_sock_group_impl_create,
|
.group_impl_create = spdk_vpp_sock_group_impl_create,
|
||||||
.group_impl_add_sock = spdk_vpp_sock_group_impl_add_sock,
|
.group_impl_add_sock = spdk_vpp_sock_group_impl_add_sock,
|
||||||
|
@ -50,6 +50,7 @@ DEFINE_STUB(spdk_sock_set_recvbuf, int, (struct spdk_sock *sock, int sz), 0);
|
|||||||
DEFINE_STUB(spdk_sock_set_sendbuf, int, (struct spdk_sock *sock, int sz), 0);
|
DEFINE_STUB(spdk_sock_set_sendbuf, int, (struct spdk_sock *sock, int sz), 0);
|
||||||
DEFINE_STUB(spdk_sock_is_ipv6, bool, (struct spdk_sock *sock), false);
|
DEFINE_STUB(spdk_sock_is_ipv6, bool, (struct spdk_sock *sock), false);
|
||||||
DEFINE_STUB(spdk_sock_is_ipv4, bool, (struct spdk_sock *sock), true);
|
DEFINE_STUB(spdk_sock_is_ipv4, bool, (struct spdk_sock *sock), true);
|
||||||
|
DEFINE_STUB(spdk_sock_is_connected, bool, (struct spdk_sock *sock), true);
|
||||||
DEFINE_STUB(spdk_sock_group_create, struct spdk_sock_group *, (void *ctx), NULL);
|
DEFINE_STUB(spdk_sock_group_create, struct spdk_sock_group *, (void *ctx), NULL);
|
||||||
DEFINE_STUB(spdk_sock_group_add_sock, int, (struct spdk_sock_group *group, struct spdk_sock *sock,
|
DEFINE_STUB(spdk_sock_group_add_sock, int, (struct spdk_sock_group *group, struct spdk_sock *sock,
|
||||||
spdk_sock_cb cb_fn, void *cb_arg), 0);
|
spdk_sock_cb cb_fn, void *cb_arg), 0);
|
||||||
|
@ -130,6 +130,7 @@ spdk_ut_sock_accept(struct spdk_sock *_sock)
|
|||||||
|
|
||||||
SPDK_CU_ASSERT_FATAL(g_ut_client_sock != NULL);
|
SPDK_CU_ASSERT_FATAL(g_ut_client_sock != NULL);
|
||||||
g_ut_client_sock->peer = new_sock;
|
g_ut_client_sock->peer = new_sock;
|
||||||
|
new_sock->peer = g_ut_client_sock;
|
||||||
|
|
||||||
return &new_sock->base;
|
return &new_sock->base;
|
||||||
}
|
}
|
||||||
@ -145,6 +146,11 @@ spdk_ut_sock_close(struct spdk_sock *_sock)
|
|||||||
if (sock == g_ut_client_sock) {
|
if (sock == g_ut_client_sock) {
|
||||||
g_ut_client_sock = NULL;
|
g_ut_client_sock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sock->peer != NULL) {
|
||||||
|
sock->peer->peer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(_sock);
|
free(_sock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -244,6 +250,14 @@ spdk_ut_sock_is_ipv4(struct spdk_sock *_sock)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
spdk_ut_sock_is_connected(struct spdk_sock *_sock)
|
||||||
|
{
|
||||||
|
struct spdk_ut_sock *sock = __ut_sock(_sock);
|
||||||
|
|
||||||
|
return (sock->peer != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_ut_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
spdk_ut_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
|
||||||
{
|
{
|
||||||
@ -331,6 +345,7 @@ static struct spdk_net_impl g_ut_net_impl = {
|
|||||||
.set_priority = spdk_ut_sock_set_priority,
|
.set_priority = spdk_ut_sock_set_priority,
|
||||||
.is_ipv6 = spdk_ut_sock_is_ipv6,
|
.is_ipv6 = spdk_ut_sock_is_ipv6,
|
||||||
.is_ipv4 = spdk_ut_sock_is_ipv4,
|
.is_ipv4 = spdk_ut_sock_is_ipv4,
|
||||||
|
.is_connected = spdk_ut_sock_is_connected,
|
||||||
.get_placement_id = spdk_ut_sock_get_placement_id,
|
.get_placement_id = spdk_ut_sock_get_placement_id,
|
||||||
.group_impl_create = spdk_ut_sock_group_impl_create,
|
.group_impl_create = spdk_ut_sock_group_impl_create,
|
||||||
.group_impl_add_sock = spdk_ut_sock_group_impl_add_sock,
|
.group_impl_add_sock = spdk_ut_sock_group_impl_add_sock,
|
||||||
@ -371,6 +386,8 @@ _sock(const char *ip, int port)
|
|||||||
|
|
||||||
server_sock = spdk_sock_accept(listen_sock);
|
server_sock = spdk_sock_accept(listen_sock);
|
||||||
SPDK_CU_ASSERT_FATAL(server_sock != NULL);
|
SPDK_CU_ASSERT_FATAL(server_sock != NULL);
|
||||||
|
CU_ASSERT(spdk_sock_is_connected(client_sock) == true);
|
||||||
|
CU_ASSERT(spdk_sock_is_connected(server_sock) == true);
|
||||||
|
|
||||||
/* Test spdk_sock_recv */
|
/* Test spdk_sock_recv */
|
||||||
iov.iov_base = test_string;
|
iov.iov_base = test_string;
|
||||||
@ -418,6 +435,11 @@ _sock(const char *ip, int port)
|
|||||||
CU_ASSERT(client_sock == NULL);
|
CU_ASSERT(client_sock == NULL);
|
||||||
CU_ASSERT(rc == 0);
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
/* On FreeBSD, it takes a small amount of time for a close to propagate to the
|
||||||
|
* other side, even in loopback. Introduce a small sleep. */
|
||||||
|
sleep(1);
|
||||||
|
CU_ASSERT(spdk_sock_is_connected(server_sock) == false);
|
||||||
|
|
||||||
rc = spdk_sock_close(&server_sock);
|
rc = spdk_sock_close(&server_sock);
|
||||||
CU_ASSERT(server_sock == NULL);
|
CU_ASSERT(server_sock == NULL);
|
||||||
CU_ASSERT(rc == 0);
|
CU_ASSERT(rc == 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user