Easier memory management
This commit is contained in:
parent
e277b86838
commit
45998b8c32
12
src/addr.c
12
src/addr.c
@ -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)
|
||||
|
41
src/alloc.c
41
src/alloc.c
@ -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;
|
||||
|
12
src/iface.c
12
src/iface.c
@ -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)
|
||||
|
12
src/io.c
12
src/io.c
@ -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)
|
||||
|
30
src/ndppd.h
30
src/ndppd.h
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
4
src/rt.c
4
src/rt.c
@ -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);
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user