OpenSIPS version you are running
version: opensips 3.6.7 (x86_64/linux)
flags: STATS: On, DISABLE_NAGLE, USE_MCAST, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, HP_MALLOC, F_PARALLEL_MALLOC, DBG_MALLOC, FAST_LOCK-ADAPTIVE_WAIT
ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535
poll method support: poll, epoll, sigio_rt, select.
git revision: eaee48e28e
main.c compiled on with gcc 10
Observed on 3.6.7. Master retains the missing per-index-state check and the unchecked
assignment/publish sequence in lineseize_subs_handl, but its outbound caller path differs,
so the reproduction below applies to 3.6.7 only. I am separately re-verifying master runtime
behaviour. This issue is independent of the inverted expiry test in lineseize_subs_handl,
corrected on master by 3595af48; the 3.6.7 reproduction below was run with the equivalent
correction applied.
Describe the bug
A line-seize SUBSCRIBE for an appearance index that is already in an active call is
accepted with 200 OK. This is the case the existing FIXME in lineseize_subs_handl
describes:
/* FIXME - check the seized idx is not already in a call */
/* do the seizing */
sca->seize_state = idx;
The 3.6.7 reproduction reaches the handler because line seizure and per-index call state are
tracked separately. sca_set_calling_line() enters sca_set_line(), which, for the
still-valid seizure used in this reproduction, invokes terminate_line_sieze() and clears
seize_state. After the dialog confirms, its callback publishes that index as active. A
subsequent initial line-seize therefore skips the existing-seizure block because
seize_state == 0. With the per-index check named by the FIXME absent, the handler assigns
the index, changes its state to SCA_STATE_SEIZED, and publishes it.
Master has a different caller path. Commit 283b529c removed the exported
sca_set_calling_line(), introduced sca_engage(), and introduced sca_validate_call_out().
That validator unlocks the line without clearing the seizure; its only in-tree
terminate_line_sieze() invocation is a comment positioned after the unlock. Consequently,
sca_engage("A") does not perform the 3.6 call-time clear. Master retains the missing
per-index-state check and unchecked assignment/publish sequence, but I am re-verifying a
master-specific runtime trigger before making a reachability claim.
There is a second effect on the published state. set_sca_index_state() overwrites the
per-index entry in place (scai->state = state), so accepting the seize replaces active
with seized rather than conflicting with it — the in-progress call is no longer
represented in the published appearance state at all.
To Reproduce
With disable_dialog_support_for_sca=0 (internal publishing mode):
- Endpoint P1 sends a
line-seize SUBSCRIBE for appearance-index=3 → 200 OK
(seize_state = 3).
- P1 sends an INVITE from the line carrying
Call-Info: <line>;appearance-index=3.
sca_set_calling_line() terminates the seizure (seize_state → 0); the callee answers,
the dialog confirms, and index 3 becomes active.
- Endpoint P2 sends a
line-seize SUBSCRIBE for appearance-index=3, while index 3 is in
the active call.
Observed:
p1_seize_status: 200
invite_status: 200
index_state_after_call: active
p2_seize_of_active_index_status: 200 <-- accepted while active
Both endpoints are software endpoints (sipp); no external SIP service is involved.
Expected behavior
A line-seize for an appearance that is already in an active call should not be granted,
and accepting a seize should not discard the appearance's existing call state in the
published NOTIFY.
Relevant System Logs
The published call-info NOTIFY after P2's accepted seize:
Call-Info: <sip:LINE>;appearance-index=3;appearance-state=seized;appearance-index=*;appearance-state=idle
Index 3 is published as seized only; the active state it held before P2's SUBSCRIBE is
gone, so watchers of the line no longer see the call in progress.
OS/environment information
- Operating System: Debian (container image)
- OpenSIPS installation: source, built from tag
3.6.7 (eaee48e28e)
- other relevant information:
presence_callinfo in internal publishing mode
(disable_dialog_support_for_sca=0); software endpoints only.
Additional context
We have a candidate patch that checks the index's current state before accepting the seize,
along with regression results, and are happy to open a PR if that shape is useful. We have
not done so because the right semantics look like a design decision rather than an obvious
fix — in particular whether a seize should be refused for every non-idle appearance, or only
for one in an active call. Seizing an appearance that is on hold appears to be a
legitimate way to resume or pick up that call, and deliberate barge-in is a real feature, so
a guard that rejects all non-idle states could break behaviour that is intended. Happy to
follow whichever direction you prefer.
OpenSIPS version you are running
Observed on 3.6.7. Master retains the missing per-index-state check and the unchecked
assignment/publish sequence in
lineseize_subs_handl, but its outbound caller path differs,so the reproduction below applies to 3.6.7 only. I am separately re-verifying master runtime
behaviour. This issue is independent of the inverted expiry test in
lineseize_subs_handl,corrected on master by
3595af48; the 3.6.7 reproduction below was run with the equivalentcorrection applied.
Describe the bug
A
line-seizeSUBSCRIBE for an appearance index that is already in an active call isaccepted with
200 OK. This is the case the existingFIXMEinlineseize_subs_handldescribes:
The 3.6.7 reproduction reaches the handler because line seizure and per-index call state are
tracked separately.
sca_set_calling_line()enterssca_set_line(), which, for thestill-valid seizure used in this reproduction, invokes
terminate_line_sieze()and clearsseize_state. After the dialog confirms, its callback publishes that index as active. Asubsequent initial line-seize therefore skips the existing-seizure block because
seize_state == 0. With the per-index check named by theFIXMEabsent, the handler assignsthe index, changes its state to
SCA_STATE_SEIZED, and publishes it.Master has a different caller path. Commit
283b529cremoved the exportedsca_set_calling_line(), introducedsca_engage(), and introducedsca_validate_call_out().That validator unlocks the line without clearing the seizure; its only in-tree
terminate_line_sieze()invocation is a comment positioned after the unlock. Consequently,sca_engage("A")does not perform the 3.6 call-time clear. Master retains the missingper-index-state check and unchecked assignment/publish sequence, but I am re-verifying a
master-specific runtime trigger before making a reachability claim.
There is a second effect on the published state.
set_sca_index_state()overwrites theper-index entry in place (
scai->state = state), so accepting the seize replacesactivewith
seizedrather than conflicting with it — the in-progress call is no longerrepresented in the published appearance state at all.
To Reproduce
With
disable_dialog_support_for_sca=0(internal publishing mode):line-seizeSUBSCRIBE forappearance-index=3→200 OK(
seize_state = 3).Call-Info: <line>;appearance-index=3.sca_set_calling_line()terminates the seizure (seize_state → 0); the callee answers,the dialog confirms, and index 3 becomes
active.line-seizeSUBSCRIBE forappearance-index=3, while index 3 is inthe active call.
Observed:
Both endpoints are software endpoints (sipp); no external SIP service is involved.
Expected behavior
A
line-seizefor an appearance that is already in an active call should not be granted,and accepting a seize should not discard the appearance's existing call state in the
published NOTIFY.
Relevant System Logs
The published
call-infoNOTIFY after P2's accepted seize:Index 3 is published as
seizedonly; theactivestate it held before P2's SUBSCRIBE isgone, so watchers of the line no longer see the call in progress.
OS/environment information
3.6.7(eaee48e28e)presence_callinfoin internal publishing mode(
disable_dialog_support_for_sca=0); software endpoints only.Additional context
We have a candidate patch that checks the index's current state before accepting the seize,
along with regression results, and are happy to open a PR if that shape is useful. We have
not done so because the right semantics look like a design decision rather than an obvious
fix — in particular whether a seize should be refused for every non-idle appearance, or only
for one in an active call. Seizing an appearance that is on hold appears to be a
legitimate way to resume or pick up that call, and deliberate barge-in is a real feature, so
a guard that rejects all non-idle states could break behaviour that is intended. Happy to
follow whichever direction you prefer.