Skip to content

Commit

Permalink
nanocoap/cache: Extend with option-only cache keygen
Browse files Browse the repository at this point in the history
To generate cache keys based on only the options of a request. This for
matching requests of a blockwise transfer with each other
  • Loading branch information
bergzand committed Nov 2, 2023
1 parent 32795ca commit 984ecd9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
20 changes: 20 additions & 0 deletions sys/include/net/nanocoap/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ int nanocoap_cache_del(const nanocoap_cache_entry_t *ce);
*/
void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key);

/**
* @brief Generates a cache key based on only the options in @p req
*
* @param[in] req The request to generate the cache key from
* @param[out] cache_key The generated cache key
*/
void nanocoap_cache_key_options_generate(const coap_pkt_t *req, uint8_t *cache_key);

/**
* @brief Generates a cache key based on only the options in @p req without
* any of the blockwise options included in the key
*
* This function can be used to correlate individual requests that are part of a
* blockwise transfer with each other.
*
* @param[in] req The request to generate the cache key from
* @param[out] cache_key The generated cache key
*/
void nanocoap_cache_key_blockreq_options_generate(const coap_pkt_t *req, uint8_t *cache_key);

/**
* @brief Compares two cache keys.
*
Expand Down
44 changes: 38 additions & 6 deletions sys/net/application_layer/nanocoap/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,10 @@ size_t nanocoap_cache_free_count(void)
return clist_count(&_empty_list_head);
}

void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key)
static void _cache_key_digest_opts(const coap_pkt_t *req, sha256_context_t *ctx,
bool include_etag,
bool include_blockwise)
{
sha256_context_t ctx;
sha256_init(&ctx);

coap_optpos_t opt = {0, 0};
uint8_t *value;

Expand All @@ -96,17 +95,50 @@ void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key)
if (optlen >= 0) {
/* gCoAP forward proxy is ETag-aware, so skip ETag option,
* see https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.2 */
if (IS_USED(MODULE_GCOAP_FORWARD_PROXY) && (opt.opt_num == COAP_OPT_ETAG)) {
if ((!include_etag) && (opt.opt_num == COAP_OPT_ETAG)) {
continue;
}
/* skip NoCacheKey,
see https://tools.ietf.org/html/rfc7252#section-5.4.6 */
if ((opt.opt_num & 0x1E) == 0x1C) {
continue;
}
sha256_update(&ctx, value, optlen);
/* Don't include blockwise (on request) so matching between
* blockwise parts is possible */
if ((!include_blockwise) && (
(opt.opt_num == COAP_OPT_BLOCK2) ||
(opt.opt_num == COAP_OPT_BLOCK1)
)) {
continue;
}
sha256_update(ctx, &opt.opt_num, sizeof(opt.opt_num));
sha256_update(ctx, value, optlen);
}
}
}

void nanocoap_cache_key_options_generate(const coap_pkt_t *req, uint8_t *cache_key)
{
sha256_context_t ctx;
sha256_init(&ctx);
_cache_key_digest_opts(req, &ctx, true, true);
sha256_final(&ctx, cache_key);
}

void nanocoap_cache_key_blockreq_options_generate(const coap_pkt_t *req, uint8_t *cache_key)
{
sha256_context_t ctx;
sha256_init(&ctx);
_cache_key_digest_opts(req, &ctx, true, false);
sha256_final(&ctx, cache_key);
}

void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key)
{
sha256_context_t ctx;
sha256_init(&ctx);

_cache_key_digest_opts(req, &ctx, !(IS_USED(MODULE_GCOAP_FORWARD_PROXY)), true);
switch (req->hdr->code) {
case COAP_METHOD_FETCH:
sha256_update(&ctx, req->payload, req->payload_len);
Expand Down

0 comments on commit 984ecd9

Please sign in to comment.