Thanks community for all replies.
I did the second try. Result is in the attachment.
This time a did it in the way proposed by Daniel-Constantin Mierla. All job is done in timer process when it iterates through all registrations looking for expired ones.
It works for all database modes except DB_ONLY.
I'm not sure about tcpconn_get() / tcpconn_put() functions. tcpconn_get() increments ref counter, but there are several function to decrement it: tcpconn_put(), tcpconn_chld_put() and atomic_dec_and_test(). When I was looking for examples in other modules I saw that tcp_read.c uses tcpconn_chld_put(), but forward.h and msg_translator.c uses only tcpconn_get() without decrementing ref counter at all.
It would be great if somebody more experienced shed some light on this.