summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2019-05-14 16:18:51 +0200
committerHans Dedecker <dedeckeh@gmail.com>2019-05-15 10:10:08 +0200
commitc0c8034bc17519c7960f40f6d796b5485cfc4cdb (patch)
treeef3079b303164e2c5313a89e97e4d8e4d6aed4b1
parentf98b7ee899d492d32c4d857aa068daf95ae5be7b (diff)
treewide: init assignment lists head
When allocating an assignment in alloc_assignment; init the circular head and lease_list circular lists. Avoids checking NULL pointer when freeing the assignment in free_assignment. Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--src/dhcpv4.c6
-rw-r--r--src/dhcpv6-ia.c8
-rw-r--r--src/odhcpd.h20
3 files changed, 22 insertions, 12 deletions
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index 9d21423..2634f65 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -1024,9 +1024,9 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
if (!a) {
if (!iface->no_dynamic_dhcp || l) {
/* Create new binding */
- a = calloc(1, sizeof(*a));
+ a = alloc_assignment(0);
if (!a) {
- syslog(LOG_ERR, "Failed to calloc binding on interface %s",
+ syslog(LOG_ERR, "Failed to alloc assignment on interface %s",
iface->ifname);
return NULL;
}
@@ -1057,7 +1057,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
} else if (((a->addr & iface->dhcpv4_mask.s_addr) !=
(iface->dhcpv4_start_ip.s_addr & iface->dhcpv4_mask.s_addr)) &&
!(a->flags & OAF_STATIC)) {
- list_del(&a->head);
+ list_del_init(&a->head);
a->addr = INADDR_ANY;
assigned = dhcpv4_assign(iface, a, reqaddr);
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index 81c2481..9559b96 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -75,10 +75,10 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable)
struct dhcp_assignment *border;
if (list_empty(&iface->ia_assignments)) {
- border = calloc(1, sizeof(*border));
+ border = alloc_assignment(0);
if (!border) {
- syslog(LOG_ERR, "Calloc failed for border on %s", iface->name);
+ syslog(LOG_ERR, "Failed to alloc border on %s", iface->name);
return -1;
}
@@ -719,7 +719,7 @@ static void handle_addrlist_change(struct netevent_handler_info *info)
while (!list_empty(&reassign)) {
c = list_first_entry(&reassign, struct dhcp_assignment, head);
- list_del(&c->head);
+ list_del_init(&c->head);
if (!assign_pd(iface, c)) {
c->assigned = 0;
list_add(&c->head, &iface->ia_assignments);
@@ -1237,7 +1237,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac
if ((!iface->no_dynamic_dhcp || (l && is_na)) &&
(iface->dhcpv6_pd || iface->dhcpv6_na)) {
/* Create new binding */
- a = calloc(1, sizeof(*a) + clid_len);
+ a = alloc_assignment(clid_len);
if (a) {
a->clid_len = clid_len;
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 9535e75..37a5a4a 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -309,11 +309,8 @@ extern struct avl_tree interfaces;
inline static void free_assignment(struct dhcp_assignment *a)
{
- if (a->head.next)
- list_del(&a->head);
-
- if (a->lease_list.next)
- list_del(&a->lease_list);
+ list_del(&a->head);
+ list_del(&a->lease_list);
if (a->dhcp_free_cb)
a->dhcp_free_cb(a);
@@ -323,6 +320,19 @@ inline static void free_assignment(struct dhcp_assignment *a)
free(a);
}
+inline static struct dhcp_assignment *alloc_assignment(size_t extra_len)
+{
+ struct dhcp_assignment *a = calloc(1, sizeof(*a) + extra_len);
+
+ if (!a)
+ return NULL;
+
+ INIT_LIST_HEAD(&a->head);
+ INIT_LIST_HEAD(&a->lease_list);
+
+ return a;
+}
+
// Exported main functions
int odhcpd_register(struct odhcpd_event *event);
int odhcpd_deregister(struct odhcpd_event *event);