]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
mem-pool: Adjust the base address if it's the network ID
authorTobias Brunner <tobias@strongswan.org>
Tue, 28 May 2024 07:41:29 +0000 (09:41 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 17 Jun 2024 12:55:43 +0000 (14:55 +0200)
Instead of just adding the offset internally, this way the reported
base address is always the first assignable address (e.g. for
192.168.0.0/24 vs. 192.168.0.1/24).

Closes strongswan/strongswan#2264

src/libcharon/attributes/mem_pool.c
src/libcharon/tests/suites/test_mem_pool.c

index b2382c46d2c6e6942163922c6d6692165f714746..95e400353c0c3cb62b8a5ddab995019bb6f74a1f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2010-2024 Tobias Brunner
  * Copyright (C) 2008-2010 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
@@ -46,11 +46,6 @@ struct private_mem_pool_t {
         */
        host_t *base;
 
-       /**
-        * whether base is the network id of the subnet on which the pool is based
-        */
-       bool base_is_network_id;
-
        /**
         * size of the pool
         */
@@ -137,22 +132,16 @@ static bool id_equals(identification_t *a, identification_t *b)
 }
 
 /**
- * convert a pool offset to an address
+ * apply the given offset to a base address
  */
-static host_t* offset2host(private_mem_pool_t *pool, int offset)
+static host_t *apply_offset(host_t *base, int offset)
 {
        chunk_t addr;
        host_t *host;
        uint32_t *pos;
 
-       offset--;
-       if (offset > pool->size)
-       {
-               return NULL;
-       }
-
-       addr = chunk_clone(pool->base->get_address(pool->base));
-       if (pool->base->get_family(pool->base) == AF_INET6)
+       addr = chunk_clone(base->get_address(base));
+       if (base->get_family(base) == AF_INET6)
        {
                pos = (uint32_t*)(addr.ptr + 12);
        }
@@ -161,11 +150,24 @@ static host_t* offset2host(private_mem_pool_t *pool, int offset)
                pos = (uint32_t*)addr.ptr;
        }
        *pos = htonl(offset + ntohl(*pos));
-       host = host_create_from_chunk(pool->base->get_family(pool->base), addr, 0);
+       host = host_create_from_chunk(base->get_family(base), addr, 0);
        free(addr.ptr);
        return host;
 }
 
+/**
+ * convert a pool offset to an address
+ */
+static host_t* offset2host(private_mem_pool_t *pool, int offset)
+{
+       offset--;
+       if (offset > pool->size)
+       {
+               return NULL;
+       }
+       return apply_offset(pool->base, offset);
+}
+
 /**
  * convert a host to a pool offset
  */
@@ -342,8 +344,7 @@ static int get_new(private_mem_pool_t *this, identification_t *id, host_t *peer)
                        entry = entry_create(id);
                        this->leases->put(this->leases, entry->id, entry);
                }
-               /* assigning offset, starting by 1 */
-               lease.offset = ++this->unused + (this->base_is_network_id ? 1 : 0);
+               lease.offset = ++this->unused;
                lease.hash = hash_addr(peer);
                array_insert(entry->online, ARRAY_TAIL, &lease);
                DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
@@ -682,13 +683,14 @@ mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
 
                if (this->size > 2)
                {
-                       /* if base is the network id we later skip the first address,
+                       /* if base is the network id we skip the first address,
                         * otherwise adjust the size to represent the actual number
                         * of assignable addresses */
                        diff = network_id_diff(base, bits);
                        if (!diff)
                        {
-                               this->base_is_network_id = TRUE;
+                               this->base->destroy(this->base);
+                               this->base = apply_offset(base, 1);
                                this->size--;
                        }
                        else
index 8d87b6ad4640a69c87c0c4e3eb5505589008b046..ae10e3a36c22847a5dea5449194306cca0c03d42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Tobias Brunner
+ * Copyright (C) 2014-2024 Tobias Brunner
  *
  * Copyright (C) secunet Security Networks AG
  *
@@ -35,6 +35,17 @@ static void assert_host(char *expected, host_t *host)
        }
 }
 
+static void assert_base(mem_pool_t *pool, char *expected)
+{
+       host_t *verifier, *base;
+
+       verifier = host_create_from_string(expected, 0);
+       base = pool->get_base(pool);
+       ck_assert_msg(verifier->ip_equals(verifier, base), "expected base %+H != "
+                                 "%+H", verifier, base);
+       verifier->destroy(verifier);
+}
+
 static void assert_acquire(mem_pool_t *pool, char *requested, char *expected,
                                                   mem_pool_op_t operation)
 {
@@ -90,26 +101,31 @@ START_TEST(test_cidr)
 
        pool = mem_pool_create("test", base, 32);
        ck_assert_int_eq(1, pool->get_size(pool));
+       assert_base(pool, "192.168.0.0");
        assert_acquires_new(pool, "192.168.0.%d", 0);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 31);
        ck_assert_int_eq(2, pool->get_size(pool));
+       assert_base(pool, "192.168.0.0");
        assert_acquires_new(pool, "192.168.0.%d", 0);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 30);
        ck_assert_int_eq(2, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
        assert_acquires_new(pool, "192.168.0.%d", 1);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 29);
        ck_assert_int_eq(6, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
        assert_acquires_new(pool, "192.168.0.%d", 1);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 24);
        ck_assert_int_eq(254, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
        assert_acquires_new(pool, "192.168.0.%d", 1);
        pool->destroy(pool);
 
@@ -125,11 +141,19 @@ START_TEST(test_cidr_offset)
        base = host_create_from_string("192.168.0.1", 0);
        pool = mem_pool_create("test", base, 31);
        ck_assert_int_eq(1, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
        assert_acquires_new(pool, "192.168.0.%d", 1);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 30);
        ck_assert_int_eq(2, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
+       assert_acquires_new(pool, "192.168.0.%d", 1);
+       pool->destroy(pool);
+
+       pool = mem_pool_create("test", base, 24);
+       ck_assert_int_eq(254, pool->get_size(pool));
+       assert_base(pool, "192.168.0.1");
        assert_acquires_new(pool, "192.168.0.%d", 1);
        pool->destroy(pool);
        base->destroy(base);
@@ -137,11 +161,13 @@ START_TEST(test_cidr_offset)
        base = host_create_from_string("192.168.0.2", 0);
        pool = mem_pool_create("test", base, 30);
        ck_assert_int_eq(1, pool->get_size(pool));
+       assert_base(pool, "192.168.0.2");
        assert_acquires_new(pool, "192.168.0.%d", 2);
        pool->destroy(pool);
 
        pool = mem_pool_create("test", base, 24);
        ck_assert_int_eq(253, pool->get_size(pool));
+       assert_base(pool, "192.168.0.2");
        assert_acquires_new(pool, "192.168.0.%d", 2);
        pool->destroy(pool);
        base->destroy(base);
@@ -149,6 +175,7 @@ START_TEST(test_cidr_offset)
        base = host_create_from_string("192.168.0.254", 0);
        pool = mem_pool_create("test", base, 24);
        ck_assert_int_eq(1, pool->get_size(pool));
+       assert_base(pool, "192.168.0.254");
        assert_acquires_new(pool, "192.168.0.%d", 254);
        pool->destroy(pool);
        base->destroy(base);
@@ -170,6 +197,7 @@ START_TEST(test_range)
        to = host_create_from_string("192.168.0.0", 0);
        pool = mem_pool_create_range("test", from, to);
        ck_assert_int_eq(1, pool->get_size(pool));
+       assert_base(pool, "192.168.0.0");
        assert_acquires_new(pool, "192.168.0.%d", 0);
        pool->destroy(pool);
 
@@ -177,6 +205,7 @@ START_TEST(test_range)
        to = host_create_from_string("192.168.0.1", 0);
        pool = mem_pool_create_range("test", from, to);
        ck_assert_int_eq(2, pool->get_size(pool));
+       assert_base(pool, "192.168.0.0");
        assert_acquires_new(pool, "192.168.0.%d", 0);
        pool->destroy(pool);
 
@@ -189,6 +218,7 @@ START_TEST(test_range)
        to = host_create_from_string("192.168.0.20", 0);
        pool = mem_pool_create_range("test", from, to);
        ck_assert_int_eq(11, pool->get_size(pool));
+       assert_base(pool, "192.168.0.10");
        assert_acquires_new(pool, "192.168.0.%d", 10);
        pool->destroy(pool);