net: lwm2m: increase packet reference to avoid packet being freed
CoAP packet w/ confirmation flag set is required to be retransmitted before it got the ACK message from the peer. However, the packet is usally unreference once it's sent to the network. Although we set the timeout as no wait when calling function net_app_send_pkt(), it's still possible that the packet is unreferenced before we got a chance to increase the packet reference by calling coap_pending_cycle(). Usually, the IP stack will generate an ARP packet first and then send out the packet. However, this is not the case when the remote is a loopback address. As issue #5101 described, when asking client to perform a firmware pull on URL "coap://127.0.0.1:7783/large". The packet will be unreferenced immediately after calling net_app_send_pkt(). Which then result in client hang. The solution to the issue is to increase the reference count on the sending packet and decrease it after the process is finished. Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
This commit is contained in:
parent
4971d2a084
commit
33030721c4
1 changed files with 12 additions and 4 deletions
|
@ -886,34 +886,42 @@ cleanup:
|
|||
int lwm2m_send_message(struct lwm2m_message *msg)
|
||||
{
|
||||
int ret;
|
||||
struct net_pkt *pkt;
|
||||
|
||||
if (!msg || !msg->ctx) {
|
||||
SYS_LOG_ERR("LwM2M message is invalid.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* protect the packet from being released inbetween net_app_send_pkt()
|
||||
* to coap_pending_cycle()
|
||||
*/
|
||||
pkt = msg->cpkt.pkt;
|
||||
net_pkt_ref(pkt);
|
||||
|
||||
msg->send_attempts++;
|
||||
ret = net_app_send_pkt(&msg->ctx->net_app_ctx, msg->cpkt.pkt,
|
||||
&msg->ctx->net_app_ctx.default_ctx->remote,
|
||||
NET_SOCKADDR_MAX_SIZE, K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (msg->type == COAP_TYPE_CON) {
|
||||
if (msg->send_attempts > 1) {
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
coap_pending_cycle(msg->pending);
|
||||
k_delayed_work_submit(&msg->ctx->retransmit_work,
|
||||
msg->pending->timeout);
|
||||
} else {
|
||||
/* if we're not expecting an ACK, free up the msg data */
|
||||
lwm2m_reset_message(msg, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
net_pkt_unref(pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16_t lwm2m_get_rd_data(u8_t *client_data, u16_t size)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue