Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nanocoap/sock: fix state handling for mismatching message ID in nanocoap_sock_request_cb() #20725

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 26 additions & 21 deletions sys/net/application_layer/nanocoap/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
enum {
STATE_REQUEST_SEND, /**< request was just sent or will be sent again */
STATE_STOP_RETRANSMIT, /**< stop retransmissions due to a matching empty ACK */
STATE_RESPONSE_OK, /**< valid response was received */
STATE_WAIT_RESPONSE, /**< waiting for a response */
};

typedef struct {
Expand Down Expand Up @@ -206,7 +206,7 @@

/* random timeout, deadline for receive retries */
uint32_t timeout = random_uint32_range((uint32_t)CONFIG_COAP_ACK_TIMEOUT_MS * US_PER_MS,
(uint32_t)CONFIG_COAP_ACK_TIMEOUT_MS * CONFIG_COAP_RANDOM_FACTOR_1000);

Check warning on line 209 in sys/net/application_layer/nanocoap/sock.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
uint32_t deadline = _deadline_from_interval(timeout);

/* check if we expect a reply */
Expand Down Expand Up @@ -234,19 +234,21 @@
res = _sock_sendv(sock, &head);
if (res <= 0) {
DEBUG("nanocoap: error sending coap request, %" PRIdSIZE "\n", res);
return res;
goto release;
}

/* no response needed and no response handler given */
if (!confirmable && !cb) {
return 0;
res = 0;
goto release;
}

/* ctx must have been released at this point */
assert(ctx == NULL);
state = STATE_WAIT_RESPONSE;
/* fall-through */
case STATE_STOP_RETRANSMIT:
case STATE_RESPONSE_OK:
case STATE_WAIT_RESPONSE: /* waiting for response, no empty ACK received */
case STATE_STOP_RETRANSMIT: /* waiting for response, empty ACK received */
if (ctx == NULL) {
DEBUG("nanocoap: waiting for response (timeout: %"PRIu32" µs)\n",
_deadline_left_us(deadline));
Expand All @@ -267,25 +269,23 @@
/* no more data */
/* sock_udp_recv_buf() needs to be called in a loop until ctx is NULL again
* to release the buffer */
if (state == STATE_STOP_RETRANSMIT) {
continue;
}
return res;
continue;
}
res = tmp;
if (res == -ETIMEDOUT) {
if (tries_left == 0) {
DEBUG("nanocoap: maximum retries reached\n");
return -ETIMEDOUT;
goto release;
}
state = STATE_REQUEST_SEND;
DEBUG("nanocoap: timeout waiting for response\n");
timeout *= 2;
deadline = _deadline_from_interval(timeout);
continue;
}
if (res < 0) {
DEBUG("nanocoap: error receiving CoAP response, %" PRIdSIZE "\n", res);
return res;
goto release;
}

/* parse response */
Expand All @@ -297,13 +297,8 @@
DEBUG("nanocoap: ID mismatch, got %u want %u\n", coap_get_id(pkt), id);
continue;
}

DEBUG("nanocoap: response code=%i\n", coap_get_code_decimal(pkt));
switch (coap_get_type(pkt)) {
case COAP_TYPE_RST:
/* TODO: handle different? */
res = -EBADMSG;
break;
case COAP_TYPE_ACK:
if (coap_get_code_raw(pkt) == COAP_CODE_EMPTY) {
/* empty ACK, wait for separate response */
Expand All @@ -315,24 +310,34 @@
continue;
}
/* fall-through */
case COAP_TYPE_RST:
case COAP_TYPE_CON:
case COAP_TYPE_NON:
state = STATE_RESPONSE_OK;
if (coap_get_type(pkt) == COAP_TYPE_RST) {
/* think about whether cb should be called on RST as well */
res = -EBADMSG;
benpicco marked this conversation as resolved.
Show resolved Hide resolved
goto release;
}
if (coap_get_type(pkt) == COAP_TYPE_CON) {
/* send ACK */
_send_ack(sock, pkt);
}
/* call user callback */
if (cb) {
res = cb(arg, pkt);
} else {
}
else {
res = _get_error(pkt);
}
break;
goto release;
}
}
}

release:
while (ctx) {
/* make sure ctx is really deleted in all cases */
_sock_recv_buf(sock, &payload, &ctx, 0);
}

return res;
}

Expand Down
Loading