Hello,
After ~6 days our tunnels stops working.
Having a look at the SAD and SPD, we can see incoherence with reqid between SAD
and SPD:
100.100.100.210[4500] 109.11.194.95[4500]
esp-udp mode=tunnel spi=3379728082(0xc9728ed2) reqid=17440(0x00004420)
....
100.100.100.210[4500] 109.11.194.95[4500]
esp-udp mode=tunnel spi=3409116770(0xcb32fe62) reqid=17439(0x0000441f)
....
--
109.11.194.95[4500] 100.100.100.210[4500]
esp-udp mode=tunnel spi=3424858610(0xcc2331f2) reqid=17440(0x00004420)
....
109.11.194.95[4500] 100.100.100.210[4500]
esp-udp mode=tunnel spi=3454863146(0xcded072a) reqid=17439(0x0000441f)
....
10.10.1.42[any] 0.0.0.0/0[any] 255
in ipsec
esp/tunnel/109.11.194.95-100.100.100.210/unique#18495
...
10.10.33.42[any] 0.0.0.0/0[any] 255
in ipsec
esp/tunnel/109.11.194.95-100.100.100.210/unique#18497
...
0.0.0.0/0[any] 10.10.1.42[any] 255
out ipsec
esp/tunnel/100.100.100.210-109.11.194.95/unique#18496
...
0.0.0.0/0[any] 10.10.33.42[any] 255
out ipsec
esp/tunnel/100.100.100.210-109.11.194.95/unique#18498
We are currently using FreeBSD, and we found this define IPSEC_MANUAL_REQID_MAX
(0x3fff == 16383). When a reqid reach this limit, FreeBSD will never use our
reqid anymore.
We take a look in charon code, and we found that you just increase a counter
each time you are creating a new reqid and use it. So we thought to change this
behavior and reuse reqids, like store reqids when they release and use them
when we want to create a new one. (We already patch the code and try it, it
works for us).
What do you think ?
Thank you for your help in advance,
Regards,
Laurent Ansel
diff --git src/libcharon/kernel/kernel_interface.c src/libcharon/kernel/kernel_interface.c
index ec35d10..2e0ae80 100644
--- src/libcharon/kernel/kernel_interface.c
+++ src/libcharon/kernel/kernel_interface.c
@@ -117,6 +117,11 @@ struct private_kernel_interface_t {
linked_list_t *listeners;
/**
+ * list of reqids that are unused
+ */
+ linked_list_t *unused_reqids;
+
+ /**
* Reqid entries indexed by reqids
*/
hashtable_t *reqids;
@@ -367,7 +372,12 @@ METHOD(kernel_interface_t, alloc_reqid, status_t,
{
/* none found, create a new entry, allocating a reqid */
entry = tmpl;
- entry->reqid = ++counter;
+
+ if (this->unused_reqids->get_count(this->unused_reqids) == 0)
+ entry->reqid = ++counter;
+ else
+ this->unused_reqids->remove_first(this->unused_reqids, &entry->reqid);
+
this->reqids_by_ts->put(this->reqids_by_ts, entry, entry);
this->reqids->put(this->reqids, entry, entry);
}
@@ -395,6 +405,7 @@ METHOD(kernel_interface_t, release_reqid, status_t,
{
if (--entry->refs == 0)
{
+ this->unused_reqids->insert_last(this->unused_reqids, entry->reqid);
entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry);
if (entry)
{
@@ -977,6 +988,7 @@ METHOD(kernel_interface_t, destroy, void,
DESTROY_IF(this->ipsec);
DESTROY_IF(this->net);
DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free);
+ this->unused_reqids->destroy(this->unused_reqids);
this->reqids->destroy(this->reqids);
this->reqids_by_ts->destroy(this->reqids_by_ts);
this->listeners->destroy(this->listeners);
@@ -1070,6 +1082,7 @@ kernel_interface_t *kernel_interface_create()
.listeners = linked_list_create(),
.mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT),
.algorithms = linked_list_create(),
+ .unused_reqids = linked_list_create(),
.reqids = hashtable_create((hashtable_hash_t)hash_reqid,
(hashtable_equals_t)equals_reqid, 8),
.reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts,