1 /** @file
2  * @brief DNS cache
3  *
4  * An cache holding dns records for faster dns resolving.
5  */
6 
7 /*
8  * Copyright (c) 2024 Endress+Hauser AG
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_NET_DNS_CACHE_H_
14 #define ZEPHYR_INCLUDE_NET_DNS_CACHE_H_
15 
16 #include <stdint.h>
17 #include <zephyr/net/dns_resolve.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/sys_clock.h>
20 
21 struct dns_cache_entry {
22 	char query[CONFIG_DNS_RESOLVER_MAX_QUERY_LEN];
23 	struct dns_addrinfo data;
24 	k_timepoint_t expiry;
25 	bool in_use;
26 };
27 
28 struct dns_cache {
29 	size_t size;
30 	struct dns_cache_entry *entries;
31 	struct k_mutex *lock;
32 };
33 
34 /**
35  * @brief Statically define and initialize a DNS queue.
36  *
37  * The cache can be accessed outside the module where it is defined using:
38  *
39  * @code extern struct dns_cache <name>; @endcode
40  *
41  * @param name Name of the cache.
42  */
43 #define DNS_CACHE_DEFINE(name, cache_size)                                                         \
44 	static K_MUTEX_DEFINE(name##_mutex);                                                       \
45 	static struct dns_cache_entry name##_entries[cache_size];                                  \
46 	static struct dns_cache name = {                                                           \
47 		.entries = name##_entries, .size = cache_size, .lock = &name##_mutex};
48 
49 /**
50  * @brief Flushes the dns cache removing all its entries.
51  *
52  * @param cache Cache to be flushed
53  * @retval 0 on success
54  * @retval On error, a negative value is returned.
55  */
56 int dns_cache_flush(struct dns_cache *cache);
57 
58 /**
59  * @brief Adds a new entry to the dns cache removing the one closest to expiry
60  * if no free space is available.
61  *
62  * @param cache Cache where the entry should be added.
63  * @param query Query which should be persisted in the cache.
64  * @param addrinfo Addrinfo resulting from the query which will be returned
65  * upon cache hit.
66  * @param ttl Time to live for the entry in seconds. This usually represents
67  * the TTL of the RR.
68  * @retval 0 on success
69  * @retval On error, a negative value is returned.
70  */
71 int dns_cache_add(struct dns_cache *cache, char const *query, struct dns_addrinfo const *addrinfo,
72 		  uint32_t ttl);
73 
74 /**
75  * @brief Removes all entries with the given query
76  *
77  * @param cache Cache where the entries should be removed.
78  * @param query Query which should be searched for.
79  * @retval 0 on success
80  * @retval On error, a negative value is returned.
81  */
82 int dns_cache_remove(struct dns_cache *cache, char const *query);
83 
84 /**
85  * @brief Tries to find the specified query entry within the cache.
86  *
87  * @param cache Cache where the entry should be searched.
88  * @param query Query which should be searched for.
89  * @param addrinfo dns_addrinfo array which will be written if the query was found.
90  * @param addrinfo_array_len Array size of the dns_addrinfo array
91  * @retval on success the amount of dns_addrinfo written into the addrinfo array will be returned.
92  * A cache miss will therefore return a 0.
93  * @retval On error a negative value is returned.
94  * -ENOSR means there was not enough space in the addrinfo array to accommodate all cache hits the
95  * array will however be filled with valid data.
96  */
97 int dns_cache_find(struct dns_cache const *cache, const char *query, struct dns_addrinfo *addrinfo,
98 		   size_t addrinfo_array_len);
99 
100 #endif /* ZEPHYR_INCLUDE_NET_DNS_CACHE_H_ */
101