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,