Skip to content

Conversation

@ammarfaizi2
Copy link
Contributor

The old DNS cache setup in dns.c was kinda clunky because it needed to
slog through everything in O(n) time. This patch series swaps it out
for something way better and tidier. Create a new C file, dns_cache.c,
just for the DNS cache stuff to keep things nice and separate.

Plus, the storage is now smarter about memory, using this compact structure:

struct gwp_dns_cache_entry {
	/**
	 * Super compact domain name and IP address list.
	 *
	 * - name_len: length of the domain name (including null terminator).
	 * - nr_i4: number of IPv4 addresses.
	 * - nr_i6: number of IPv6 addresses.
	 * - block: flexible array member that contains:
	 *     - The first name_len octets are the domain name.
	 *     - The next nr_i4 * 4 octets are IPv4 addresses.
	 *     - The next nr_i6 * 16 octets are IPv6 addresses.
	 */
	uint8_t		name_len;
	uint8_t		nr_i4;
	uint8_t		nr_i6;
	uint8_t		block[];
};

Also, the lookup now uses a hashmap, so it's super fast, O(1) on average.

There are six commits in this series:

1) Initial DNS cache rework.
A preparation patch to split the DNS cache code into a separate C file.
This implementation uses a better data structure, a hashmap, which has
an average O(1) time complexity. The cache storage is also more compact
and more efficient with respect to memory.

2) Add nr_entries for accounting purpose.
Add a counter to keep track of the number of entries in the cache.

3) Add a forward declaration of 'struct addrinfo'.
To avoid missing declaration when included before netdb.h.

4) Don't return expired cache entry.
gwp_dns_cache_getent() should only return a cache entry if the domain
name is found and is not expired. The expired case was not handled. Fix
it by returning -ETIMEDOUT.

5) Introduce entry block getter functions.
Introduce gwp_dns_cache_entget_i4() and gwp_dns_cache_entget_i6()
to get pointers to the list of IP addresses.

6) Replace the old DNS cache system with a new one.
The new DNS cache library uses a hashmap data structure, which
has an average O(1) time complexity for lookup. It's also cleaner
to split the caching logic into a smaller, more manageable
C files.

The following changes since commit 6749e79cef6c9f46957d961da5a044d929eb7245:

  gwproxy: Swap out the old DNS setup for the new library version (2025-07-17 19:06:30 +0700)

are available in the Git repository at:

  https://github.com/ammarfaizi2/gwproxy.git dns-cache

for you to fetch changes up to 82c86a7256d63fc4d849c4c81f8688cbb9b284a9:

  gwproxy/dns: Replace the old DNS cache system with a new one. (2025-07-19 22:48:15 +0700)

----------------------------------------------------------------
Ammar Faizi (6):
      gwproxy/dns_cache: Initial DNS cache rework
      gwproxy/dns_cache: Add `nr_entries` for accounting purpose
      gwproxy/dns_cache: Add a forward declaration of 'struct addrinfo'
      gwproxy/dns_cache: Don't return expired cache entry
      gwproxy/dns_cache: Introduce entry block getter functions
      gwproxy/dns: Replace the old DNS cache system with a new one.

 Makefile                |   2 +-
 src/gwproxy/dns.c       | 275 +++++++-----------------
 src/gwproxy/dns_cache.c | 447 ++++++++++++++++++++++++++++++++++++++++
 src/gwproxy/dns_cache.h | 120 +++++++++++
 4 files changed, 648 insertions(+), 196 deletions(-)
 create mode 100644 src/gwproxy/dns_cache.c
 create mode 100644 src/gwproxy/dns_cache.h

A preparation patch to split the DNS cache code into a separate C file.
This implementation uses a better data structure, a hashmap, which has
an average O(1) time complexity. The cache storage is also more compact
and more efficient with respect to memory.

Signed-off-by: Ammar Faizi <[email protected]>
Add a counter to keep track of the number of entries in the cache.

Signed-off-by: Ammar Faizi <[email protected]>
To avoid missing declaration when included before netdb.h.

Fixes: 1df5cc8 ("gwproxy/dns_cache: Initial DNS cache rework")
Signed-off-by: Ammar Faizi <[email protected]>
`gwp_dns_cache_getent()` should only return a cache entry if the domain
name is found and is not expired. The expired case was not handled. Fix
it by returning -ETIMEDOUT.

Signed-off-by: Ammar Faizi <[email protected]>
Introduce `gwp_dns_cache_entget_i4()` and `gwp_dns_cache_entget_i6()`
to get pointers to the list of IP addresses.

Signed-off-by: Ammar Faizi <[email protected]>
The new DNS cache library uses a hashmap data structure, which
has an average O(1) time complexity for lookup. It's also cleaner
to split the caching logic into a smaller, more manageable
C files.

Signed-off-by: Ammar Faizi <[email protected]>
@ammarfaizi2 ammarfaizi2 merged commit 88dc650 into master Jul 19, 2025
1 check passed
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