Make sure to run `accept_enable` when handling `accept_backoff_ev`
This fixes issue #99.
There's a situation where the connection pressure is solved but redsocks doesn't resume listening to new connections.
redsocks_conn_maxis hit,conn_pressureruns.- There are no long-idle connections, so
conn_pressureadds theaccept_backoff_evevent and disables all listeners. - Some time passes.
accept_backoff_evgets triggered andredsocks_accept_backoffgets called.conn_pressure_ongoing() == true, soconn_pressureruns.- This time there's a connection that's more than 7440s old.
conn_pressuredrops it and returns. - Now
conn_pressure_ongoing() == false, butaccept_enableisn't called because the conditional was evaluated before runningconn_pressure. redsocks_accept_backoffreturns, soaccept_backoff_evis not pending anymore andaccept_enablewill never be called.
Thank you for the test-case! The fix seems a bit questionable to me - enabling listeners on every exponential backoff iteration also looks like invariant violation, but the bug is there for sure.
I could have added an accept_enable() in redsocks.c:1032, right before the return, but my reasoning was that the accept_backoff_ev event being pending "means" that redsocks isn't listening at the moment—and the rest of the code treats it that way. For example conn_pressure_lowered calls accept_enable() only if this event is pending.
So, in this way, event_add(&accept_backoff_ev, &tvdelay) semantically is 'stop listening for tvdelay'. If the event handler can return without re-enabling the listeners this meaning is lost. I chose to call accept_enable() as soon as possible within the event handler to prevent another bug like this one from ever happening.