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,

Reply via email to