• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* coap_cache.h -- Caching of CoAP requests
2 *
3 * Copyright (C) 2020-2023 Olaf Bergmann <bergmann@tzi.org>
4 *
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10 
11 /**
12  * @file coap_cache.h
13  * @brief Provides a simple cache request storage for CoAP requests
14  */
15 
16 #ifndef COAP_CACHE_H_
17 #define COAP_CACHE_H_
18 
19 #include "coap_forward_decls.h"
20 
21 /**
22  * @ingroup application_api
23  * @defgroup cache Cache Support
24  * API for Cache-Key and Cache-Entry.
25  * See https://rfc-editor.org/rfc/rfc7252#section-5.4.2
26  * @{
27  */
28 
29 /**
30  * Callback to free off the app data when the cache-entry is
31  * being deleted / freed off.
32  *
33  * @param data  The app data to be freed off.
34  */
35 typedef void (*coap_cache_app_data_free_callback_t)(void *data);
36 
37 typedef enum coap_cache_session_based_t {
38   COAP_CACHE_NOT_SESSION_BASED,
39   COAP_CACHE_IS_SESSION_BASED
40 } coap_cache_session_based_t;
41 
42 typedef enum coap_cache_record_pdu_t {
43   COAP_CACHE_NOT_RECORD_PDU,
44   COAP_CACHE_RECORD_PDU
45 } coap_cache_record_pdu_t;
46 
47 /**
48  * Calculates a cache-key for the given CoAP PDU. See
49  * https://rfc-editor.org/rfc/rfc7252#section-5.4.2
50  * for an explanation of CoAP cache keys.
51  *
52  * Specific CoAP options can be removed from the cache-key.  Examples of
53  * this are the Block1 and Block2 options - which make no real sense including
54  * them in a client or server environment, but should be included in a proxy
55  * caching environment where things are cached on a per block basis.
56  * This is done globally by calling the coap_cache_ignore_options()
57  * function.
58  *
59  * NOTE: The returned cache-key needs to be freed off by the caller by
60  * calling coap_cache_delete_key().
61  *
62  * @param session The session to add into cache-key if @p session_based
63  *                is set.
64  * @param pdu     The CoAP PDU for which a cache-key is to be
65  *                calculated.
66  * @param session_based COAP_CACHE_IS_SESSION_BASED if session based
67  *                      cache-key, else COAP_CACHE_NOT_SESSION_BASED.
68  *
69  * @return        The returned cache-key or @c NULL if failure.
70  */
71 coap_cache_key_t *coap_cache_derive_key(const coap_session_t *session,
72                                         const coap_pdu_t *pdu,
73                                         coap_cache_session_based_t session_based);
74 
75 /**
76  * Calculates a cache-key for the given CoAP PDU. See
77  * https://rfc-editor.org/rfc/rfc7252#section-5.4.2
78  * for an explanation of CoAP cache keys.
79  *
80  * Specific CoAP options can be removed from the cache-key.  Examples of
81  * this are the Block1 and Block2 options - which make no real sense including
82  * them in a client or server environment, but should be included in a proxy
83  * caching environment where things are cached on a per block basis.
84  * This is done individually by specifying @p cache_ignore_count and
85  * @p cache_ignore_options .
86  *
87  * NOTE: The returned cache-key needs to be freed off by the caller by
88  * calling coap_cache_delete_key().
89  *
90  * @param session The session to add into cache-key if @p session_based
91  *                is set.
92  * @param pdu     The CoAP PDU for which a cache-key is to be
93  *                calculated.
94  * @param session_based COAP_CACHE_IS_SESSION_BASED if session based
95  *                      cache-key, else COAP_CACHE_NOT_SESSION_BASED.
96  * @param ignore_options The array of options to ignore.
97  * @param ignore_count   The number of options to ignore.
98  *
99  * @return        The returned cache-key or @c NULL if failure.
100  */
101 coap_cache_key_t *coap_cache_derive_key_w_ignore(const coap_session_t *session,
102                                                  const coap_pdu_t *pdu,
103                                                  coap_cache_session_based_t session_based,
104                                                  const uint16_t *ignore_options,
105                                                  size_t ignore_count);
106 
107 /**
108  * Delete the cache-key.
109  *
110  * @param cache_key The cache-key to delete.
111  */
112 void coap_delete_cache_key(coap_cache_key_t *cache_key);
113 
114 /**
115  * Define the CoAP options that are not to be included when calculating
116  * the cache-key. Options that are defined as Non-Cache and the Observe
117  * option are always ignored.
118  *
119  * @param context   The context to save the ignored options information in.
120  * @param options   The array of options to ignore.
121  * @param count     The number of options to ignore.  Use 0 to reset the
122  *                  options matching.
123  *
124  * @return          @return @c 1 if successful, else @c 0.
125  */
126 int coap_cache_ignore_options(coap_context_t *context,
127                               const uint16_t *options, size_t count);
128 
129 /**
130  * Create a new cache-entry hash keyed by cache-key derived from the PDU.
131  *
132  * If @p session_based is set, then this cache-entry will get deleted when
133  * the session is freed off.
134  * If @p record_pdu is set, then the copied PDU will get freed off when
135  * this cache-entry is deleted.
136  *
137  * The cache-entry is maintained on a context hash list.
138  *
139  * @param session   The session to use to derive the context from.
140  * @param pdu       The pdu to use to generate the cache-key.
141  * @param record_pdu COAP_CACHE_RECORD_PDU if to take a copy of the PDU for
142  *                   later use, else COAP_CACHE_NOT_RECORD_PDU.
143  * @param session_based COAP_CACHE_IS_SESSION_BASED if to associate this
144  *                      cache-entry with the the session (which is embedded
145  *                      in the cache-entry), else COAP_CACHE_NOT_SESSION_BASED.
146  * @param idle_time Idle time in seconds before cache-entry is expired.
147  *                  If set to 0, it does not expire (but will get
148  *                  deleted if the session is deleted and it is session_based).
149  *
150  * @return          The returned cache-key or @c NULL if failure.
151  */
152 coap_cache_entry_t *coap_new_cache_entry(coap_session_t *session,
153                                          const coap_pdu_t *pdu,
154                                          coap_cache_record_pdu_t record_pdu,
155                                          coap_cache_session_based_t session_based,
156                                          unsigned int idle_time);
157 
158 /**
159  * Remove a cache-entry from the hash list and free off all the appropriate
160  * contents apart from app_data.
161  *
162  * @param context     The context to use.
163  * @param cache_entry The cache-entry to remove.
164  */
165 void coap_delete_cache_entry(coap_context_t *context,
166                              coap_cache_entry_t *cache_entry);
167 
168 /**
169  * Searches for a cache-entry identified by @p cache_key. This
170  * function returns the corresponding cache-entry or @c NULL
171  * if not found.
172  *
173  * @param context    The context to use.
174  * @param cache_key  The cache-key to get the hashed coap-entry.
175  *
176  * @return The cache-entry for @p cache_key or @c NULL if not found.
177  */
178 coap_cache_entry_t *coap_cache_get_by_key(coap_context_t *context,
179                                           const coap_cache_key_t *cache_key);
180 
181 /**
182  * Searches for a cache-entry corresponding to @p pdu. This
183  * function returns the corresponding cache-entry or @c NULL if not
184  * found.
185  *
186  * @param session    The session to use.
187  * @param pdu        The CoAP request to search for.
188  * @param session_based COAP_CACHE_IS_SESSION_BASED if session based
189  *                     cache-key to be used, else COAP_CACHE_NOT_SESSION_BASED.
190  *
191  * @return The cache-entry for @p request or @c NULL if not found.
192  */
193 coap_cache_entry_t *coap_cache_get_by_pdu(coap_session_t *session,
194                                           const coap_pdu_t *pdu,
195                                           coap_cache_session_based_t session_based);
196 
197 /**
198  * Returns the PDU information stored in the @p coap_cache entry.
199  *
200  * @param cache_entry The CoAP cache entry.
201  *
202  * @return The PDU information stored in the cache_entry or NULL
203  *         if the PDU was not initially copied.
204  */
205 const coap_pdu_t *coap_cache_get_pdu(const coap_cache_entry_t *cache_entry);
206 
207 /**
208  * Stores @p data with the given cache entry. This function
209  * overwrites any value that has previously been stored with @p
210  * cache_entry.
211  *
212  * @param cache_entry The CoAP cache entry.
213  * @param data The data pointer to store with wih the cache entry. Note that
214  *             this data must be valid during the lifetime of @p cache_entry.
215  * @param callback The callback to call to free off this data when the
216  *                 cache-entry is deleted, or @c NULL if not required.
217  */
218 void coap_cache_set_app_data(coap_cache_entry_t *cache_entry, void *data,
219                              coap_cache_app_data_free_callback_t callback);
220 
221 /**
222  * Returns any application-specific data that has been stored with @p
223  * cache_entry using the function coap_cache_set_app_data(). This function will
224  * return @c NULL if no data has been stored.
225  *
226  * @param cache_entry The CoAP cache entry.
227  *
228  * @return The data pointer previously stored or @c NULL if no data stored.
229  */
230 void *coap_cache_get_app_data(const coap_cache_entry_t *cache_entry);
231 
232 /** @} */
233 
234 #endif  /* COAP_CACHE_H */
235