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

Handle separate response #86

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

codable
Copy link

@codable codable commented May 30, 2017

This PR aims at fixing #83. The theory is when receiving empty-message, it inserts the request into send queue and update the retransmit_cnt to be bigger than COAP_DEFAULT_MAX_RETRANSMIT, thus it will be dropped after the timer timeout, and the timeout is set be as if it is the last try of retransmission. When the actually response is received, the special request is removed immediately from the queue.

@codable
Copy link
Author

codable commented Jun 1, 2017

any comments?

@obgm
Copy link
Owner

obgm commented Jun 1, 2017

I haven't yet time to look into the patch, sorry. But will do soon.

Copy link
Owner

@obgm obgm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice trick to handle the separate response issue, thanks for providing the patch. Can you please resubmit with the requested changes made and a commit message that follows the contribution guidelines? Thanks!

src/net.c Outdated
while (q) {
if (coap_address_equals(dst, &context->sendqueue->remote) &&
token_match(token, token_length,
context->sendqueue->pdu->hdr->token,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I presume this should be q instead of context->sendqueue, no?

src/net.c Outdated
token_match(token, token_length,
context->sendqueue->pdu->hdr->token,
context->sendqueue->pdu->hdr->token_length) &&
context->sendqueue->retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(see previous comment)

src/net.c Outdated
token_match(token, token_length,
context->sendqueue->pdu->hdr->token,
context->sendqueue->pdu->hdr->token_length) &&
context->sendqueue->retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can encapsulate the condition ...retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT in some way so that the semantics are easier to understand, e.g.:

static inline int
is_separate(const coap_queue_t *node) {
   return node->retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT;
}

and then:

...coap_address_equals(....) && token_match(....) && is_separate(context->sendqueue)...

src/net.c Outdated


/* Find separate response's request */
if (sent == NULL) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me some time to understand why this will actually work---can you include a comment that explains why in this case, the sendqueue may contain the sent request despite sent being NULL?

@codable
Copy link
Author

codable commented Jun 4, 2017

Thanks for pointing out those mistakes and suggestions.

@codable codable force-pushed the separate-response branch 2 times, most recently from 4764567 to d31ed51 Compare June 5, 2017 10:11
@codable
Copy link
Author

codable commented Jun 6, 2017

any more comments? @obgm

@obgm
Copy link
Owner

obgm commented Jun 7, 2017

Looks good at a first glance. I will do a quick test within the next days and merge on success,

src/net.c Outdated
* cannot be be of that type.
*/
if (sent == NULL && rcvd->pdu->hdr->type != COAP_MESSAGE_ACK) {
coap_remove_separate_from_queue(context, &rcvd->remote,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coap_remove_separate_from_queue() removes a node from the send queue without deleting it afterwards. This results in a memory leak whenever a separate response is received before the maximum retransmission timeout is reached. You can check this e.g. with valgrind:

  1. Start the example server: coap-server
  2. From a different terminal, send a query for the async resource:
    valgrind -v coap-client -v9 -B 200 coap://[::1]/async?15
  3. (Optional:) Compare with very late response:
    valgrind -v coap-client -v9 -B 200 coap://[::1] /async?150

An optimal solution to this should also avoid doubling most of the code in coap_cancel_all_messages().

Copy link
Owner

@obgm obgm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the previous comments. After a few tests, I found a serious memory leak that needs to be fixed before this can be merged.

@codable codable force-pushed the separate-response branch 2 times, most recently from d646d90 to 2f42f89 Compare June 12, 2017 03:19
@codable
Copy link
Author

codable commented Jun 13, 2017

@obgm I updated the code to free the memory by not removing the separate request from the send queue before calling the actually handler and free them after calling handler. But I'm sorry, I cannot build with examples to verify memory leak as you suggested. The error is

a2x --doctype manpage --format manpage coap-client.txt
a2x: ERROR: "xmllint" --nonet --noout --valid "libcoap/examples/coap-client.xml" returned non-zero exit status 4

@obgm
Copy link
Owner

obgm commented Jun 13, 2017

Ugh, yes, saw that xmllint error before. IIRC, it has to do with a missing package that for some reason is not listed in the dependencies of a2x (some missing DTD or so). A quick and dirty workaround would be to pass --disable-documentation to configure.

@codable
Copy link
Author

codable commented Jun 14, 2017

I tested and it seems no memory leak found now.

@codable
Copy link
Author

codable commented Jun 19, 2017

any more comments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants