Menu

#100 acceptor issues logout after client logon after logout()

open
nobody
None
5
2013-03-15
2013-03-15
No

This is a revisit of ID: 3047737

When the logout() method is used to force an acceptor to logout a connected client, subsequent attempts by the client to logon result in the acceptor immediately sending a logout after the initial logon messages are exchanged.

This is seen in version 1.13.3 of the quickfix engine.

The logout() method sets the enabled state in Session.cpp to false. On the next call to void Session::next( const UtcTimeStamp& timeStamp ) this forces the acceptor to send a logout to the client:

if( !isEnabled() || !isLogonTime(timeStamp) )
{
if( isLoggedOn() )
{
if( !m_state.sentLogout() )
{
m_state.onEvent( "Initiated logout request" );
generateLogout( m_state.logoutReason() );
}
}
else
return;
}

When the client attempts a subsequent logon, the enabled state is still false.

In void Session::nextLogon( const Message& logon, const UtcTimeStamp& timeStamp ) the enabled state is not changed so it remains false but the acceptor has sent a logon message to the client thus completing the logon sequence, the client now thinks it is logged on.

On the next call to void Session::next( const UtcTimeStamp& timeStamp ) the acceptor, seeing that the enabled state is still false generates a logout.

From this point on the client will continue to logon and be immediately logged out and there appears to be no way to change this behaviour.

If we look at how an explicit logout from the client is treated in void Session::nextLogout( const Message& logout, const UtcTimeStamp& timeStamp )
we see that the enabled state is not changed to false and the client is subsequently able to logon again without the spurious logout being sent by the acceptor.

I think it is reasonable to expect that the acceptor should be in the same state after a client initiated logout or a logout initiated by the logout() method.

As a work around, in Session.cpp, I have modified void Session::nextLogon( const Message& logon, const UtcTimeStamp& timeStamp ) to set the enabled state to true for an acceptor:

if ( !m_state.initiate()
|| (m_state.receivedReset() && !m_state.sentReset()) )
{
if( logon.isSetField(m_state.heartBtInt()) )
logon.getField( m_state.heartBtInt() );
m_state.onEvent( "Received logon request" );
generateLogon( logon );
m_state.onEvent( "Responding to logon request" );
this->logon(); // @@@
}
else
m_state.onEvent( "Received logon response" );

This appears to fix the immediate problem, and clients that are forced to logout by the acceptor can now successfully logon again.

Discussion


Log in to post a comment.