connlim: a connection's slot given back once

releaseparam() gave the connection limits' slot back without clearing
param->connlim: a second call, made on the event loops' end of a relayed
client, gave it back again, letting one more connection in for each
such end while another held its slot, or, with no connlimconf, followed
param->srv, cleared by the first call. It is cleared now.

A UDP session taken over by the new service on a reload gave its slot
back but kept connlim set, so the new service's authorization did not
count it, and its end gave it back a second time. It is counted again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Vladimir Dubrovin 2026-10-27 00:03:23 +03:00
parent e3ef7bb54a
commit bd4db18413
2 changed files with 4 additions and 0 deletions

View File

@ -419,7 +419,9 @@ void releaseparam(struct clientparam * param) {
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
/* once: a second release must not give the slot back again */
if(param->connlim) stopconnlims(param);
param->connlim = 0;
/* a slot held in the newest service on the listener after a reload */
if(param->newsrv){
slotrelease(param->newsrv);

View File

@ -433,7 +433,9 @@ static void udpadopt(struct udpstate *st){
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
/* counted again by the new service's authorization */
if(param->connlim) stopconnlims(param);
param->connlim = 0;
param->bandlimfunc = NULL;
param->bandlims[0] = param->bandlimsout[0] = NULL;
param->trafcountfunc = NULL;