-
Notifications
You must be signed in to change notification settings - Fork 377
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
CoAP Packet Deduplication #791
Open
mlasch
wants to merge
2
commits into
eclipse-wakaama:main
Choose a base branch
from
husqvarnagroup:gardena/ml/coap-packet-deduplication
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* CoAP message deduplication tracking. | ||
* RFC7252 section 4.2 | ||
*/ | ||
|
||
#include <stdbool.h> | ||
|
||
#include "message_dedup.h" | ||
#include <internals.h> | ||
#include <liblwm2m.h> | ||
|
||
void coap_cleanup_message_deduplication_step(coap_msg_dedup_t **message_dedup, const time_t current_time, | ||
time_t *timeout) { | ||
LOG_DBG("Entering"); | ||
coap_msg_dedup_t *message_dedup_check = *message_dedup; | ||
coap_msg_dedup_t *message_dedup_check_prev = *message_dedup; | ||
while (message_dedup_check != NULL) { | ||
time_t diff = current_time - message_dedup_check->timestamp; | ||
if (diff >= LWM2M_COAP_MESSAGE_EXCHANGE_LIFETIME) { | ||
LOG_ARG_DBG("Message %d deduplication period ended", message_dedup_check->mid); | ||
if (message_dedup_check_prev != *message_dedup) { | ||
message_dedup_check_prev->next = message_dedup_check->next; | ||
} else { | ||
*message_dedup = message_dedup_check->next; | ||
message_dedup_check_prev = message_dedup_check->next; | ||
} | ||
coap_msg_dedup_t *message_dedup_check_next = message_dedup_check->next; | ||
lwm2m_free(message_dedup_check); | ||
message_dedup_check = message_dedup_check_next; | ||
} else { | ||
LOG_ARG_DBG("Message %d check deduplication", message_dedup_check->mid); | ||
time_t message_dedup_timeout; | ||
if ((message_dedup_timeout = | ||
(message_dedup_check->timestamp + LWM2M_COAP_MESSAGE_EXCHANGE_LIFETIME) - current_time) < 0) { | ||
message_dedup_timeout = 0; | ||
} | ||
if (message_dedup_timeout < *timeout) { | ||
LOG_ARG_DBG("Message %d check again in %ds deduplication", message_dedup_check->mid, | ||
message_dedup_timeout); | ||
*timeout = message_dedup_timeout; | ||
} | ||
message_dedup_check_prev = message_dedup_check; | ||
message_dedup_check = message_dedup_check->next; | ||
} | ||
} | ||
} | ||
|
||
bool coap_check_message_duplication(coap_msg_dedup_t **message_dedup, const uint16_t mid, const void *session, | ||
uint8_t *dedup_coap_error_code) { | ||
LOG_DBG("Entering"); | ||
coap_msg_dedup_t *message_dedup_check = *message_dedup; | ||
while (message_dedup_check != NULL) { | ||
bool is_equal = lwm2m_session_is_equal(message_dedup_check->session, (void *)session, NULL); | ||
if (message_dedup_check->mid == mid && is_equal) { | ||
LOG_ARG_DBG("Duplicate, ignore mid %d (session: %p)", mid, session); | ||
*dedup_coap_error_code = message_dedup_check->coap_response_code; | ||
return true; | ||
} | ||
message_dedup_check = message_dedup_check->next; | ||
} | ||
LOG_ARG_DBG("Register mid %d (session: %p) for deduplication check", mid, session); | ||
/* The message was not received in the past. Remember for future checks. */ | ||
coap_msg_dedup_t *new_message; | ||
new_message = lwm2m_malloc(sizeof(coap_msg_dedup_t)); | ||
if (new_message == NULL) { | ||
/* Memory allocation failed, mark packet as duplicate. Further allocations during packet processing would fail | ||
* anyway. */ | ||
return true; | ||
} | ||
memset(new_message, 0, sizeof(coap_msg_dedup_t)); | ||
new_message->mid = mid; | ||
new_message->session = (void *)session; | ||
new_message->timestamp = lwm2m_gettime(); | ||
|
||
/* Add message id to deduplication list */ | ||
coap_msg_dedup_t *message_dedup_temp = *message_dedup; | ||
*message_dedup = new_message; | ||
(*message_dedup)->next = message_dedup_temp; | ||
|
||
return false; | ||
} | ||
|
||
bool coap_deduplication_set_response_code(coap_msg_dedup_t **message_dedup, const uint16_t mid, const void *session, | ||
const uint8_t coap_response_code) { | ||
LOG_DBG("Entering"); | ||
coap_msg_dedup_t *message_dedup_check = *message_dedup; | ||
while (message_dedup_check != NULL) { | ||
bool is_equal = lwm2m_session_is_equal(message_dedup_check->session, (void *)session, NULL); | ||
if (message_dedup_check->mid == mid && is_equal) { | ||
LOG_ARG_DBG("Set response code %" PRIu8 " to message mid %" PRIu16, coap_response_code, mid); | ||
message_dedup_check->coap_response_code = coap_response_code; | ||
return true; | ||
} | ||
message_dedup_check = message_dedup_check->next; | ||
} | ||
return false; | ||
} | ||
|
||
void coap_deduplication_free(lwm2m_context_t *ctx) { | ||
LOG_DBG("Remove and free the whole message deduplication list"); | ||
while (ctx->message_dedup != NULL) { | ||
coap_msg_dedup_t *msg_dedup; | ||
msg_dedup = ctx->message_dedup; | ||
ctx->message_dedup = ctx->message_dedup->next; | ||
lwm2m_free(msg_dedup); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#ifndef _COAP_MESSAGE_DEDUP_H_ | ||
#define _COAP_MESSAGE_DEDUP_H_ | ||
|
||
#include <stdint.h> | ||
#include <time.h> | ||
|
||
#include <liblwm2m.h> | ||
|
||
typedef struct _coap_msg_dedup_ { | ||
struct _coap_msg_dedup_ *next; | ||
uint16_t mid; | ||
void *session; | ||
uint8_t coap_response_code; | ||
time_t timestamp; | ||
} coap_msg_dedup_t; | ||
|
||
/** | ||
* Cleanup message ids after EXCHANGE_LIFETIME. | ||
* @param message_dedup list of message ids for deduplication | ||
* @param current_time current timestamp | ||
* @param timeout next timeout in main loop | ||
*/ | ||
void coap_cleanup_message_deduplication_step(coap_msg_dedup_t **message_dedup, time_t current_time, time_t *timeout); | ||
|
||
/** | ||
* Check whether a message was already received. Add new messages to the deduplication tracking list. | ||
* @param message_dedup list of message ids for deduplication | ||
* @param mid message id | ||
* @param session pointer to the session the message was received from | ||
* @param coap_response_code CoAP response code to be used for answering duplicate messages | ||
* @return true if the message was already seen within in the EXCHANGE_LIFETIME window, false otherwise. | ||
*/ | ||
bool coap_check_message_duplication(coap_msg_dedup_t **message_dedup, uint16_t mid, const void *session, | ||
uint8_t *coap_response_code); | ||
|
||
/** | ||
* Set response code to be used in acks to a duplicate message. Acknowledgements to duplicate messages must have the | ||
* same CoAP return code as the relies to the first received message. | ||
* @param message_dedup list of message ids for deduplication | ||
* @param mid message id | ||
* @param session pointer to the session the message was received from | ||
* @param coap_response_code CoAP response code to be used for answering duplicate messages | ||
* @return false if no matching message was found, this is an internal error and should not happen | ||
*/ | ||
bool coap_deduplication_set_response_code(coap_msg_dedup_t **message_dedup, uint16_t mid, const void *session, | ||
uint8_t coap_response_code); | ||
|
||
/** | ||
* Remove and free the whole message deduplication list | ||
* @param ctx lwm2m context | ||
*/ | ||
void coap_deduplication_free(lwm2m_context_t *ctx); | ||
|
||
#endif // _COAP_MESSAGE_DEDUP_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear if this really belongs here. Probably it does together with the complete struct definition as we need it in the context. But then it should probably be prefixed by
lwm2m_
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to store the list somewhere, the lwm2m context was the easiest place, for that I needed this forward declaration. The message duplication tracking list is an implementation detail of the CoAP layer and might fit better there. The context structure was available everywhere I needed access though. Problem is, there is no clean separation between LwM2M and CoAP in Wakaama.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that we don't have that nice separation between CoAP and LwM2M. But the forward declaration doesn't work properly together with the typedef.