Easier memory management

This commit is contained in:
Daniel Adolfsson 2019-12-19 14:25:17 +01:00
parent e277b86838
commit 45998b8c32
9 changed files with 89 additions and 55 deletions

View File

@ -35,11 +35,7 @@ const char *nd_ntoa(const nd_addr_t *addr)
static int index;
static char buf[3][64];
if (addr == NULL) {
return "(null)";
}
return inet_ntop(AF_INET6, addr, buf[index++ % 3], 64);
return addr ? inet_ntop(AF_INET6, addr, buf[index++ % 3], 64) : "(null)";
}
bool nd_addr_is_multicast(const nd_addr_t *addr)
@ -175,11 +171,7 @@ const char *nd_ll_ntoa(const nd_lladdr_t *addr)
static int index;
static char buf[3][64];
if (addr == NULL) {
return "(null)";
}
return ether_ntoa_r((struct ether_addr *)addr, buf[index++ % 3]);
return addr ? ether_ntoa_r((struct ether_addr *)addr, buf[index++ % 3]) : "(null)";
}
bool nd_ll_addr_is_unspecified(const nd_lladdr_t *lladdr)

View File

@ -16,7 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with ndppd. If not, see <https://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -24,9 +23,14 @@
# define NDPPD_ALLOC_SIZE 16384
#endif
#ifndef NDPPD_MAX_ALLOC
# define NDPPD_MAX_ALLOC 128
#endif
#include "ndppd.h"
typedef struct ndL_chunk ndL_chunk_t;
typedef struct ndL_obj ndL_obj_t;
struct ndL_chunk {
ndL_chunk_t *next;
@ -34,8 +38,13 @@ struct ndL_chunk {
size_t size;
};
struct ndL_obj {
ndL_obj_t *next;
};
static ndL_chunk_t *ndL_chunks;
static size_t ndL_alloc_size = NDPPD_ALLOC_SIZE;
static ndL_obj_t *ndL_free_objects[NDPPD_MAX_ALLOC >> 3];
char *nd_strdup(const char *str)
{
@ -45,13 +54,39 @@ char *nd_strdup(const char *str)
return buf;
}
void nd_free(void *ptr, size_t size)
{
if (size == 0 || size > NDPPD_MAX_ALLOC) {
abort();
}
size = (size + 7U) & ~7U;
unsigned int bucket = (size >> 3) - 1;
ND_LL_PREPEND(ndL_free_objects[bucket], (ndL_obj_t *)ptr, next);
}
void *nd_alloc(size_t size)
{
assert(size > 0 && size < 512);
if (size == 0 || size > NDPPD_MAX_ALLOC) {
abort();
}
// To keep everything properly aligned, we'll make sure it's multiple of 8.
/* To keep everything properly aligned, we'll make sure it's multiple of 8. */
size = (size + 7U) & ~7U;
/* See if we can reuse an object. */
unsigned int bucket = (size >> 3) - 1;
ndL_obj_t *obj = ndL_free_objects[bucket];
if (obj) {
ND_LL_DELETE(ndL_free_objects[bucket], obj, next);
return obj;
}
/* See if we have any chunks with enough space left. */
for (ndL_chunk_t *chunk = ndL_chunks; chunk; chunk = chunk->next) {
if (chunk->free >= size) {
void *ptr = (void *)chunk + chunk->size - chunk->free;

View File

@ -54,7 +54,7 @@ extern int nd_conf_retrans_limit;
extern int nd_conf_retrans_time;
extern bool nd_conf_keepalive;
static nd_iface_t *ndL_first_iface, *ndL_first_free_iface;
static nd_iface_t *ndL_first_iface;
static nd_io_t *ndL_io;
//! Used when daemonizing to make sure the parent process does not restore these flags upon exit.
@ -506,13 +506,7 @@ nd_iface_t *nd_iface_open(const char *name, unsigned index)
nd_lladdr_t *lladdr = (nd_lladdr_t *)LLADDR((struct sockaddr_dl *)(sysctl_buf + sizeof(struct if_msghdr)));
#endif
iface = ndL_first_free_iface;
if (iface) {
ND_LL_DELETE(ndL_first_free_iface, iface, next);
} else {
iface = ND_ALLOC(nd_iface_t);
}
iface = ND_NEW(nd_iface_t);
*iface = (nd_iface_t){
.index = index,
@ -553,7 +547,7 @@ void nd_iface_close(nd_iface_t *iface)
#endif
ND_LL_DELETE(ndL_first_iface, iface, next);
ND_LL_PREPEND(ndL_first_free_iface, iface, next);
ND_DELETE(iface);
}
static void ndL_get_local_addr(nd_iface_t *iface, nd_addr_t *addr)

View File

@ -40,7 +40,7 @@
#include "ndppd.h"
static nd_io_t *ndL_first_io, *ndL_first_free_io;
static nd_io_t *ndL_first_io;
#ifndef NDPPD_NO_USE_EPOLL
static int ndL_epoll_fd;
@ -96,13 +96,7 @@ static nd_io_t *ndL_create(int fd)
return false;
}
nd_io_t *io = ndL_first_free_io;
if (io) {
ND_LL_DELETE(ndL_first_free_io, io, next);
} else {
io = ND_ALLOC(nd_io_t);
}
nd_io_t *io = ND_NEW(nd_io_t);
*io = (nd_io_t){ .fd = fd };
@ -160,7 +154,7 @@ void nd_io_close(nd_io_t *io)
#endif
ND_LL_DELETE(ndL_first_io, io, next);
ND_LL_PREPEND(ndL_first_free_io, io, next);
ND_DELETE(io);
}
ssize_t nd_io_send(nd_io_t *io, const struct sockaddr *addr, size_t addrlen, const void *msg, size_t msglen)

View File

@ -40,6 +40,7 @@ typedef struct nd_lladdr nd_lladdr_t;
typedef struct nd_rt_route nd_rt_route_t;
typedef struct nd_rt_addr nd_rt_addr_t;
typedef struct nd_ml nd_ml_t;
typedef struct nd_sub nd_sub_t;
typedef void(nd_io_handler_t)(nd_io_t *io, int events);
@ -100,20 +101,27 @@ struct nd_proxy {
};
struct nd_session {
nd_session_t *next;
nd_session_t *next_r;
nd_rule_t *rule;
nd_addr_t tgt;
nd_addr_t tgt_r;
int ons_count; /* Number of outgoing NS messages. */
long ons_time; /* Last time we sent a NS message. */
long ins_time; /* Last time this session was the target of an incoming NS. */
long state_time; /* Time when session entered it's current state. */
nd_session_t *next; /* Next session in ndL_sessions. */
nd_session_t *next_r; /* Next session in ndL_sessions_r. */
nd_rule_t *rule; /* */
nd_addr_t tgt; /* Target address. */
nd_addr_t tgt_r; /* Rewritten target address. */
int ons_count; /* Number of outgoing NS messages. */
long ons_time; /* Last time we sent a NS message. */
long ins_time; /* Last time this session was the target of an incoming NS. */
long state_time; /* Time when session entered it's current state. */
nd_state_t state;
nd_iface_t *iface;
nd_sub_t *subs;
bool autowired; /* If this session had a route set up. */
};
struct nd_sub {
nd_sub_t *next;
nd_addr_t addr;
nd_lladdr_t lladdr;
};
struct nd_rule {
nd_rule_t *next;
nd_proxy_t *proxy;
@ -227,7 +235,8 @@ struct nd_io {
; \
} while (0)
#define ND_ALLOC(type) (type *)nd_alloc(sizeof(type))
#define ND_NEW(type) (type *)nd_alloc(sizeof(type))
#define ND_DELETE(ptr) nd_free((ptr), sizeof((ptr)[0]))
/*
* ndppd.c
@ -309,6 +318,7 @@ nd_rule_t *nd_rule_create(nd_proxy_t *proxy);
*/
void *nd_alloc(size_t size);
void nd_free(void *ptr, size_t size);
char *nd_strdup(const char *str);
void nd_alloc_cleanup();

View File

@ -41,7 +41,7 @@ nd_proxy_t *nd_proxy_create(const char *ifname)
return NULL;
}
proxy = ND_ALLOC(nd_proxy_t);
proxy = ND_NEW(nd_proxy_t);
*proxy = (nd_proxy_t){ 0 };
strcpy(proxy->ifname, ifname);

View File

@ -70,7 +70,7 @@ static void ndL_new_route(nd_rt_route_t *route)
if ((new_route = ndL_free_routes)) {
ND_LL_DELETE(ndL_free_routes, new_route, next);
} else {
new_route = ND_ALLOC(nd_rt_route_t);
new_route = ND_NEW(nd_rt_route_t);
}
*new_route = *route;
@ -140,7 +140,7 @@ static void ndL_new_addr(unsigned index, nd_addr_t *addr, unsigned pflen)
if ((rt_addr = ndL_free_addrs)) {
ND_LL_DELETE(ndL_free_addrs, rt_addr, next);
} else {
rt_addr = ND_ALLOC(nd_rt_addr_t);
rt_addr = ND_NEW(nd_rt_addr_t);
}
ND_LL_PREPEND(ndL_addrs, rt_addr, next);

View File

@ -20,7 +20,7 @@
nd_rule_t *nd_rule_create(nd_proxy_t *proxy)
{
nd_rule_t *rule = ND_ALLOC(nd_rule_t);
nd_rule_t *rule = ND_NEW(nd_rule_t);
*rule = (nd_rule_t){ .proxy = proxy, .target = proxy->target };

View File

@ -34,7 +34,6 @@ extern bool nd_conf_keepalive;
#define NDL_BUCKET(a) (nd_addr_hash(a) % NDPPD_SESSION_BUCKETS)
static nd_session_t *ndL_free_sessions;
static nd_session_t *ndL_sessions[NDPPD_SESSION_BUCKETS];
static nd_session_t *ndL_sessions_r[NDPPD_SESSION_BUCKETS];
@ -59,6 +58,7 @@ void nd_session_handle_ns(nd_session_t *session, const nd_addr_t *src, const nd_
session->ins_time = nd_current_time;
if (session->state != ND_STATE_VALID && session->state != ND_STATE_STALE) {
/* Register sub */
return;
}
@ -77,6 +77,20 @@ void nd_session_handle_ns(nd_session_t *session, const nd_addr_t *src, const nd_
void nd_session_handle_na(nd_session_t *session)
{
if (session->state == ND_STATE_VALID) {
return;
}
/*if (!nd_addr_is_unspecified(&q)) {
nd_log_error("testing quickness.. ");
nd_lladdr_t *tgt_ll = !nd_ll_addr_is_unspecified(&session->rule->target) ? &session->rule->target : NULL;
nd_iface_send_na(session->rule->proxy->iface, &q, &z, //
&session->tgt, tgt_ll, session->rule->proxy->router);
memset(&q, 0, sizeof(q));
}*/
if (session->state != ND_STATE_VALID) {
nd_log_debug("Session [%s] %s -> VALID", session->rule->proxy->ifname, nd_ntoa(&session->tgt));
@ -88,13 +102,7 @@ void nd_session_handle_na(nd_session_t *session)
nd_session_t *nd_session_create(nd_rule_t *rule, const nd_addr_t *tgt)
{
nd_session_t *session = ndL_free_sessions;
if (session) {
ND_LL_DELETE(ndL_free_sessions, session, next);
} else {
session = ND_ALLOC(nd_session_t);
}
nd_session_t *session = ND_NEW(nd_session_t);
*session = (nd_session_t){
.rule = rule,
@ -162,10 +170,11 @@ void nd_session_update(nd_session_t *session)
ND_LL_DELETE(ndL_sessions[NDL_BUCKET(&session->tgt)], session, next);
ND_LL_DELETE(ndL_sessions_r[NDL_BUCKET(&session->tgt_r)], session, next_r);
ND_LL_PREPEND(ndL_free_sessions, session, next);
nd_log_debug("session [%s] %s INVALID -> (deleted)", //
session->rule->proxy->ifname, nd_ntoa(&session->tgt));
ND_DELETE(session);
break;
case ND_STATE_VALID:
@ -239,7 +248,7 @@ nd_session_t *nd_session_find_r(const nd_addr_t *tgt, const nd_iface_t *iface)
void nd_session_update_all()
{
for (int i = 0; i < NDPPD_SESSION_BUCKETS; i++) {
ND_LL_FOREACH(ndL_sessions[i], session, next) {
ND_LL_FOREACH_S(ndL_sessions[i], session, tmp, next) {
nd_session_update(session);
}
}