### Description During OpenSSL 1.1.1 integration it was necessary to use per-worker SSL_CTX —instantiated in `tls/tls_mod.c`. This is still required for OpenSSL 3.x integration.
This is a retrospective root cause analysis of why this duplicated SSL_CTX is needed.
#### Reproduction
1. Instead of creating repeating SSL_CTX (one-per-worker) have all workers use a single SSL_CTX 2. Observation: intermittent connection failures 3. Observation: if `tls` is using only EC keys, the connections will succeed
#### Root Cause Analysis
OpenSSL RSA BN operations are multi-threaded ready (can be used in single-process multi-threaded applications). However the BN operations depend crucially on each thread reporting different `pthread_self()` values. At runtime `pthread_self()` values can be reused and are only different for all running threads in a single process.
When rank 0 forks the worker processes their `pthread_self()` values will overlap. This will result in invalid BN computations and lead to failure of RSA connections. In a sense the workers perform “identify theft”.
There is no mechanism in pthreads to reset the thread ids; they are opaque handles.
In contrast, OpenSSL ECDSA operations do not invoke `pthread_self()` and do not require unique thread IDs.
Notes
- no action is required; this is purely a historical note - I have added a code comment: https://github.com/kamailio/kamailio/commit/29007ada5bc9e07ede3cdbce285f04d1... - I will leave this issue up for a few days knowledge sharing
Do you refer to the next code block?
- https://github.com/kamailio/kamailio/blob/master/src/modules/tls/tls_mod.c#L...
If yes, as I can see it, the `tls_fix_domains_cfg()` is executed for `rank == PROC_SIPINIT` when libssl is >=1.1.x, which means it is done only for the first SIP worker process (with the rank 1).
The code is in `tls_domain.c` where `d->ctx` is an **array of SSL_CTX** instead of a single SSL_CTX. Each worker has a personal copy of the SSL_CTX and uses `d->ctx[process_no]` .
In theory for each domain we could use a single SSL_CTX instead of duplicating it max_procs times, so this issue answers the question : Why is `d->ctx` an array of the same SSL_CTX instead of a single copy of an SSL_CTX?
The roots of this go back 1.1.1 where OpenSSL removed the ability of `CRYPTO_set_id_callback` (from 1.0.2). Then a process could generate a unique ID and "pretend" to be a different thread.
In OpenSSL 1.1.1+ the id is reported using `pthread_self()` - while this is unique within a process it is not unique across multiple workers.
Do you refer to the next code block?
* https://github.com/kamailio/kamailio/blob/master/src/modules/tls/tls_mod.c#L451-L471
If yes, as I can see it, the `tls_fix_domains_cfg()` is executed for `rank == PROC_SIPINIT` when libssl is >=1.1.x, which means it is done only for the first SIP worker process (with the rank 1).
Closed #3709 as completed.