diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2020-12-24 20:05:01 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2020-12-24 20:05:01 -0500 |
commit | 655453a195d821dee53c13d1deaece8afc82731e (patch) | |
tree | 9d301624f24f3d0078e10041957104036bf1f53f /src/sock_addr_cache.c | |
parent | 1212f60991f89ff4549584500195c66bb2915690 (diff) | |
download | lighttpd-git-655453a195d821dee53c13d1deaece8afc82731e.tar.gz |
[core] inet_ntop_cache -> sock_addr_cache
* rename inet_ntop_cache.[ch] to sock_addr_cache.[ch]
* reimplement as separate caches for IPv4 and IPv6
Diffstat (limited to 'src/sock_addr_cache.c')
-rw-r--r-- | src/sock_addr_cache.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/sock_addr_cache.c b/src/sock_addr_cache.c new file mode 100644 index 00000000..28d9a9ba --- /dev/null +++ b/src/sock_addr_cache.c @@ -0,0 +1,69 @@ +#include "first.h" + +#include "sock_addr_cache.h" + +#include "sys-socket.h" +#include <string.h> + +#include "buffer.h" +#include "sock_addr.h" + + +int sock_addr_cache_inet_ntop_copy_buffer(buffer * const restrict b, const sock_addr * const restrict saddr) +{ + #define NTOP_CACHE_MAX 4 + static int ndx4; + static struct { struct in_addr ipv4; } ntop4_cache[NTOP_CACHE_MAX]; + static struct { char s[INET_ADDRSTRLEN+1]; } ntop4_strs[NTOP_CACHE_MAX]; + #ifdef HAVE_IPV6 + static int ndx6; + static struct { struct in6_addr ipv6; } ntop6_cache[NTOP_CACHE_MAX]; + static struct { char s[INET6_ADDRSTRLEN+1]; } ntop6_strs[NTOP_CACHE_MAX]; + #endif + switch (saddr->plain.sa_family) { + case AF_INET: + for (int i = 0; i < NTOP_CACHE_MAX; ++i) { + if (ntop4_cache[i].ipv4.s_addr == saddr->ipv4.sin_addr.s_addr) { + buffer_copy_string(b, ntop4_strs[i].s); + return 0; + } + } + break; + #ifdef HAVE_IPV6 + case AF_INET6: + for (int i = 0; i < NTOP_CACHE_MAX; ++i) { + if (0 == memcmp(ntop6_cache[i].ipv6.s6_addr, + saddr->ipv6.sin6_addr.s6_addr, 16)) { + buffer_copy_string(b, ntop6_strs[i].s); + return 0; + } + } + break; + #endif + default: + break; + } + + if (0 != sock_addr_inet_ntop_copy_buffer(b, saddr)) { + buffer_string_set_length(b, 0); + return -1; + } + + switch (saddr->plain.sa_family) { + case AF_INET: + ntop4_cache[ndx4].ipv4.s_addr = saddr->ipv4.sin_addr.s_addr; + memcpy(ntop4_strs+ndx4, b->ptr, buffer_string_length(b)+1); + if (++ndx4 == NTOP_CACHE_MAX) ndx4 = 0; + break; + #ifdef HAVE_IPV6 + case AF_INET6: + memcpy(ntop6_cache[ndx6].ipv6.s6_addr,saddr->ipv6.sin6_addr.s6_addr,16); + memcpy(ntop6_strs+ndx6, b->ptr, buffer_string_length(b)+1); + if (++ndx6 == NTOP_CACHE_MAX) ndx6 = 0; + break; + #endif + default: + break; + } + return 0; +} |