usnistgov / jsip

JSIP: Java SIP specification Reference Implementation (moved from java.net)
Other
288 stars 131 forks source link

Deadlock in SIPServerTransactionImpl ? #78

Open kpouer opened 2 years ago

kpouer commented 2 years ago

Hi, I have a SipDialog whose lastTransaction is a SipServerTransactionImpl

The state is Completed state (because it received a 491 on a RE-INVITE) until a timer sets it to Terminated (according to RFC3261 page 127 I think). I am trying to send a RE-INVITE before the timer is triggered, so it is blocked in the ReInviteSender at this line 452: ((SIPServerTransaction)SIPDialog.this.lastTransaction).waitForTermination();

When the timer is triggered the state changes to _TERMINATED but if the transport is not reliable (UDP), then the this.terminationSemaphore.release(); will never be called and the ReInviteSender will remains blocked in the semaphore forever

@Override
public void setState(int newState) {
    // Set this timer for connection caching
    // of incoming connections.
    if (newState == TransactionState._TERMINATED && this.isReliable()
            && (!getSIPStack().cacheServerConnections)) {
        // Set a time after which the connection
        // is closed.
        this.collectionTime = TIMER_J;
        this.terminationSemaphore.release();
    }

    super.setState(newState);

}

In fact I'm not sure about the good thing to do in that case for now I replaced the test with

if (newState == TransactionState._TERMINATED && (!isReliable() || (this.isReliable() && (!getSIPStack().cacheServerConnections)))) {

so the release is called also on UDP transport.