]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
charon-tkm: Add get_dst_host getter to SAD
authorReto Buerki <reet@codelabs.ch>
Fri, 19 Dec 2014 07:54:22 +0000 (08:54 +0100)
committerMartin Willi <martin@revosec.ch>
Fri, 20 Feb 2015 12:34:53 +0000 (13:34 +0100)
This function returns the destination host of an SAD entry for given
reqid, spi and protocol arguments or NULL if not found.

src/charon-tkm/src/tkm/tkm_kernel_sad.c
src/charon-tkm/src/tkm/tkm_kernel_sad.h
src/charon-tkm/tests/kernel_sad_tests.c

index f8f23a8f8c0d95b2db26de45bfc287e63b968823..3394b58af79c07fce0bdaf56826a0b936fddbbd2 100644 (file)
@@ -113,6 +113,19 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
                   entry->spi == *spi && entry->proto == *proto;
 }
 
+/**
+ * Find a list entry with given reqid, spi and proto values.
+ */
+static bool sad_entry_match_dst(sad_entry_t * const entry,
+                                                               const u_int32_t * const reqid,
+                                                               const u_int32_t * const spi,
+                                                               const u_int8_t * const proto)
+{
+       return entry->reqid == *reqid &&
+                  entry->spi   == *spi &&
+                  entry->proto == *proto;
+}
+
 /**
  * Compare two SAD entries for equality.
  */
@@ -196,6 +209,32 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
        return id;
 }
 
+METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
+       private_tkm_kernel_sad_t * const this, const u_int32_t reqid,
+       const u_int32_t spi, const u_int8_t proto)
+{
+       host_t *dst = NULL;
+       sad_entry_t *entry = NULL;
+
+       this->mutex->lock(this->mutex);
+       const status_t res = this->data->find_first(this->data,
+                                                                                               (linked_list_match_t)sad_entry_match_dst,
+                                                                                               (void**)&entry, &reqid, &spi, &proto);
+       if (res == SUCCESS && entry)
+       {
+               dst = entry->dst;
+               DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"
+                        " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto);
+       }
+       else
+       {
+               DBG3(DBG_KNL, "no SAD entry found for reqid %u, spi %x, proto: %u",
+                        reqid, ntohl(spi), proto);
+       }
+       this->mutex->unlock(this->mutex);
+       return dst;
+}
+
 METHOD(tkm_kernel_sad_t, _remove, bool,
        private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
 {
@@ -250,6 +289,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create()
                .public = {
                        .insert = _insert,
                        .get_esa_id = _get_esa_id,
+                       .get_dst_host = _get_dst_host,
                        .remove = __remove,
                        .destroy = _destroy,
                },
index 39388f8a8a23fe40e6181723e729eead1d637a38..38b19dd01bc857357e24a3b3e381db8260064415 100644 (file)
@@ -62,6 +62,17 @@ struct tkm_kernel_sad_t {
                                 const host_t * const src, const host_t * const dst,
                                 const u_int32_t spi, const u_int8_t proto);
 
+       /**
+        * Get destination host for entry with given parameters.
+        *
+        * @param reqid                 reqid of CHILD SA
+        * @param spi                   SPI of CHILD SA
+        * @param proto                 protocol of CHILD SA (ESP/AH)
+        * @return                              destination host of entry if found, NULL otherwise
+        */
+       host_t * (*get_dst_host)(tkm_kernel_sad_t * const this,
+                         const u_int32_t reqid, const u_int32_t spi, const u_int8_t proto);
+
        /**
         * Remove entry with given ESA id from SAD.
         *
index 7eb2ff8e692274fed949ebbaae283b40838e2769..b9ab3cb5e926cc9a963a561a8ec4215ef91d77e1 100644 (file)
@@ -81,6 +81,29 @@ START_TEST(test_get_esa_id_nonexistent)
 }
 END_TEST
 
+START_TEST(test_get_dst_host)
+{
+       host_t *addr = host_create_from_string("127.0.0.1", 1024);
+       tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+       fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
+                               "Error inserting SAD entry");
+
+       host_t *dst = sad->get_dst_host(sad, 54, 42, 50);
+       fail_unless(addr->equals(addr, dst), "Error getting dst host");
+       sad->destroy(sad);
+       addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_get_dst_host_nonexistent)
+{
+       tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+       fail_unless(sad->get_dst_host(sad, 1, 12, 50) == NULL,
+                               "Got dst for nonexistent SAD entry");
+       sad->destroy(sad);
+}
+END_TEST
+
 START_TEST(test_remove)
 {
        host_t *addr = host_create_from_string("127.0.0.1", 1024);
@@ -128,6 +151,11 @@ Suite *make_kernel_sad_tests()
        tcase_add_test(tc, test_get_esa_id_nonexistent);
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("get_dst_host");
+       tcase_add_test(tc, test_get_dst_host);
+       tcase_add_test(tc, test_get_dst_host_nonexistent);
+       suite_add_tcase(s, tc);
+
        tc = tcase_create("remove");
        tcase_add_test(tc, test_remove);
        tcase_add_test(tc, test_remove_nonexistent);