net: lwm2m: Clean up context on stop
When lwm2m_rd_client_stop() was called and immediately followed by lwm2m_rd_client_start() it leaked the file handle for existing socket. Problem can be fixed when rd_client_stop() does not move state machine to IDLE, but instead DEREGISTER and then allow state machine to move forward. I added a blocking wait for rd_client_stop() because it needs to wait for proper clean up. I also move couple of lwm2m_engine_context_close() to set_sm_state() event handler or similarly in lwm2m_engine.c there was couple of places where context was not properly cleaned. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
parent
f6965ac930
commit
43c988d43e
2 changed files with 38 additions and 18 deletions
|
@ -5591,8 +5591,9 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
{
|
{
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
int flags;
|
int flags;
|
||||||
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
if (client_ctx->load_credentials) {
|
if (client_ctx->load_credentials) {
|
||||||
|
@ -5636,10 +5637,9 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
ret = setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_SEC_TAG_LIST,
|
ret = setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_SEC_TAG_LIST,
|
||||||
tls_tag_list, sizeof(tls_tag_list));
|
tls_tag_list, sizeof(tls_tag_list));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("Failed to set TLS_SEC_TAG_LIST option: %d",
|
ret = -errno;
|
||||||
errno);
|
LOG_ERR("Failed to set TLS_SEC_TAG_LIST option: %d", ret);
|
||||||
lwm2m_engine_context_close(client_ctx);
|
goto error;
|
||||||
return -errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_ctx->hostname_verify && (client_ctx->desthostname != NULL)) {
|
if (client_ctx->hostname_verify && (client_ctx->desthostname != NULL)) {
|
||||||
|
@ -5656,9 +5656,9 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
/** restore character */
|
/** restore character */
|
||||||
client_ctx->desthostname[client_ctx->desthostnamelen] = tmp;
|
client_ctx->desthostname[client_ctx->desthostnamelen] = tmp;
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("Failed to set TLS_HOSTNAME option: %d", errno);
|
ret = -errno;
|
||||||
lwm2m_engine_context_close(client_ctx);
|
LOG_ERR("Failed to set TLS_HOSTNAME option: %d", ret);
|
||||||
return -errno;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5674,18 +5674,31 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
||||||
|
|
||||||
if (connect(client_ctx->sock_fd, &client_ctx->remote_addr,
|
if (connect(client_ctx->sock_fd, &client_ctx->remote_addr,
|
||||||
addr_len) < 0) {
|
addr_len) < 0) {
|
||||||
LOG_ERR("Cannot connect UDP (-%d)", errno);
|
ret = -errno;
|
||||||
lwm2m_engine_context_close(client_ctx);
|
LOG_ERR("Cannot connect UDP (%d)", ret);
|
||||||
return -errno;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(client_ctx->sock_fd, F_GETFL, 0);
|
flags = fcntl(client_ctx->sock_fd, F_GETFL, 0);
|
||||||
if (flags == -1) {
|
if (flags == -1) {
|
||||||
return -errno;
|
ret = -errno;
|
||||||
|
LOG_ERR("fcntl(F_GETFL) failed (%d)", ret);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
fcntl(client_ctx->sock_fd, F_SETFL, flags | O_NONBLOCK);
|
ret = fcntl(client_ctx->sock_fd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
if (ret == -1) {
|
||||||
|
ret = -errno;
|
||||||
|
LOG_ERR("fcntl(F_SETFL) failed (%d)", ret);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("Connected, sock id %d", client_ctx->sock_fd);
|
||||||
|
|
||||||
return lwm2m_socket_add(client_ctx);
|
return lwm2m_socket_add(client_ctx);
|
||||||
|
|
||||||
|
error:
|
||||||
|
lwm2m_engine_context_close(client_ctx);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri)
|
int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri)
|
||||||
|
|
|
@ -155,8 +155,10 @@ static void set_sm_state(uint8_t sm_state)
|
||||||
sm_state == ENGINE_DEREGISTERED) &&
|
sm_state == ENGINE_DEREGISTERED) &&
|
||||||
(client.engine_state >= ENGINE_DO_REGISTRATION &&
|
(client.engine_state >= ENGINE_DO_REGISTRATION &&
|
||||||
client.engine_state <= ENGINE_DEREGISTER_SENT)) {
|
client.engine_state <= ENGINE_DEREGISTER_SENT)) {
|
||||||
|
lwm2m_engine_context_close(client.ctx);
|
||||||
event = LWM2M_RD_CLIENT_EVENT_DISCONNECT;
|
event = LWM2M_RD_CLIENT_EVENT_DISCONNECT;
|
||||||
} else if (sm_state == ENGINE_NETWORK_ERROR) {
|
} else if (sm_state == ENGINE_NETWORK_ERROR) {
|
||||||
|
lwm2m_engine_context_close(client.ctx);
|
||||||
client.retry_delay = 1 << client.retries;
|
client.retry_delay = 1 << client.retries;
|
||||||
client.retries++;
|
client.retries++;
|
||||||
if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) {
|
if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) {
|
||||||
|
@ -231,6 +233,7 @@ static void sm_handle_failure_state(enum sm_engine_state sm_state)
|
||||||
event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
|
event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lwm2m_engine_context_close(client.ctx);
|
||||||
set_sm_state(sm_state);
|
set_sm_state(sm_state);
|
||||||
|
|
||||||
if (event > LWM2M_RD_CLIENT_EVENT_NONE && client.event_cb) {
|
if (event > LWM2M_RD_CLIENT_EVENT_NONE && client.event_cb) {
|
||||||
|
@ -456,7 +459,6 @@ static int do_deregister_reply_cb(const struct coap_packet *response,
|
||||||
|
|
||||||
if (code == COAP_RESPONSE_CODE_DELETED) {
|
if (code == COAP_RESPONSE_CODE_DELETED) {
|
||||||
LOG_INF("Deregistration success");
|
LOG_INF("Deregistration success");
|
||||||
lwm2m_engine_context_close(client.ctx);
|
|
||||||
set_sm_state(ENGINE_DEREGISTERED);
|
set_sm_state(ENGINE_DEREGISTERED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +680,6 @@ static int sm_do_bootstrap_reg(void)
|
||||||
set_sm_state(ENGINE_BOOTSTRAP_REG_SENT);
|
set_sm_state(ENGINE_BOOTSTRAP_REG_SENT);
|
||||||
} else {
|
} else {
|
||||||
LOG_ERR("Bootstrap registration err: %d", ret);
|
LOG_ERR("Bootstrap registration err: %d", ret);
|
||||||
lwm2m_engine_context_close(client.ctx);
|
|
||||||
set_sm_state(ENGINE_NETWORK_ERROR);
|
set_sm_state(ENGINE_NETWORK_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,7 +897,6 @@ static int sm_do_registration(void)
|
||||||
set_sm_state(ENGINE_REGISTRATION_SENT);
|
set_sm_state(ENGINE_REGISTRATION_SENT);
|
||||||
} else {
|
} else {
|
||||||
LOG_ERR("Registration err: %d", ret);
|
LOG_ERR("Registration err: %d", ret);
|
||||||
lwm2m_engine_context_close(client.ctx);
|
|
||||||
set_sm_state(ENGINE_NETWORK_ERROR);
|
set_sm_state(ENGINE_NETWORK_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,7 +951,8 @@ static int sm_do_deregister(void)
|
||||||
msg = lwm2m_get_message(client.ctx);
|
msg = lwm2m_get_message(client.ctx);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
LOG_ERR("Unable to get a lwm2m message!");
|
LOG_ERR("Unable to get a lwm2m message!");
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto close_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->type = COAP_TYPE_CON;
|
msg->type = COAP_TYPE_CON;
|
||||||
|
@ -992,7 +993,9 @@ static int sm_do_deregister(void)
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
lwm2m_reset_message(msg, true);
|
lwm2m_reset_message(msg, true);
|
||||||
|
close_ctx:
|
||||||
lwm2m_engine_context_close(client.ctx);
|
lwm2m_engine_context_close(client.ctx);
|
||||||
|
set_sm_state(ENGINE_DEREGISTERED);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,12 +1132,16 @@ void lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx,
|
||||||
if (sm_is_registered() && deregister) {
|
if (sm_is_registered() && deregister) {
|
||||||
set_sm_state(ENGINE_DEREGISTER);
|
set_sm_state(ENGINE_DEREGISTER);
|
||||||
} else {
|
} else {
|
||||||
set_sm_state(ENGINE_IDLE);
|
set_sm_state(ENGINE_DEREGISTERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INF("Stop LWM2M Client: %s", log_strdup(client.ep_name));
|
LOG_INF("Stop LWM2M Client: %s", log_strdup(client.ep_name));
|
||||||
|
|
||||||
k_mutex_unlock(&client.mutex);
|
k_mutex_unlock(&client.mutex);
|
||||||
|
|
||||||
|
while (get_sm_state() != ENGINE_IDLE) {
|
||||||
|
k_sleep(K_MSEC(STATE_MACHINE_UPDATE_INTERVAL_MS / 2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lwm2m_rd_client_update(void)
|
void lwm2m_rd_client_update(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue