Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When Acceptor initiates Logoff, it doesn't wait for the Logoff response #856

Open
gbirchmeier opened this issue Jun 5, 2024 · 1 comment

Comments

@gbirchmeier
Copy link
Member

If the Acceptor initiates the Logoff, it won't wait for the Logoff response.

The Init will send the Logoff reply, which increments the outgoing seqnum, but Acceptor will never process it (I think the Accepctor-side transport later just discards it). This leaves the server's reception-seqnum one increment behind where it should be.

If the Init has ResetOnLogon=Y, then no problem, because the seqnum will reset on the next Logon.

However, if the Init has ResetOnLogon=N, then on next logon the message flow will be something like:

  1. Init-> SeqNum=10 Logon .... but server expects SeqNum=9
  2. <-Acc Logon response
  3. <-Acc ResendRequest BeginSeqNo=9 EndSeqNo=0
  4. Init-> SequenceReset
  5. recovery complete, communication continues as normal

Here is a real log from a pair of apps I'm working with. The Initiator is named "client" and the Acceptor is named "server". At the start, "server" rejects the logon and sends a logoff.

20240605-18:19:04.271 : 8=FIXT.1.1|9=101|35=A|34=1|49=client|52=20240605-18:19:04.269|56=server|98=0|108=10|141=Y|553=testuser|554=LLL|1137=9|10=031|
20240605-18:19:04.274 : 8=FIXT.1.1|9=106|35=5|34=1|49=server|52=20240605-18:19:04.274|56=client|58=Rejected Logon Attempt: Password Expired|1409=8|10=068|
20240605-18:19:04.275 : 8=FIXT.1.1|9=55|35=5|34=2|49=client|52=20240605-18:19:04.275|56=server|10=072|

The above client->server logout (with seqnum=2) is never processed by server.

At this point, client thinks the next seqnum should be 3, but server thinks it should be 2.

Therefore, after the next logon, server requests a ResendRequest, because it thinks client's Logon should have had 34=2 instead of 3.

20240605-19:19:07.930 : 8=FIXT.1.1|9=74|35=A|34=3|49=client|52=20240605-19:19:07.918|56=server|98=0|108=10|1137=9|10=184|
20240605-19:19:07.972 : 8=FIXT.1.1|9=74|35=A|34=2|49=server|52=20240605-19:19:07.965|56=client|98=0|108=10|1137=9|10=185|
20240605-19:19:07.991 : 8=FIXT.1.1|9=64|35=2|34=3|49=server|52=20240605-19:19:07.971|56=client|7=1|16=0|10=200|
20240605-19:19:07.993 : 8=FIXT.1.1|9=97|35=4|34=1|43=Y|49=client|52=20240605-19:19:07.993|56=server|122=20240605-19:19:07.992|36=4|123=Y|10=113|
20240605-19:19:18.002 : 8=FIXT.1.1|9=55|35=0|34=4|49=client|52=20240605-19:19:18.001|56=server|10=062|
20240605-19:19:18.003 : 8=FIXT.1.1|9=55|35=0|34=4|49=server|52=20240605-19:19:18.001|56=client|10=062|
@gbirchmeier
Copy link
Member Author

The cause is in Session.Next(MessageBuilder), in the catch (RejectLogon e) block, or in the Disconnect() that is called inside it.

Disconnect closes the responder without allowing it to wait for the Logout. When the Logout arrives, nothing is listening. On the next logon, I think the queued received data on the socket is flushed when the responder is... reset or reinitialized.

I need to take a deeper dig into the code to really "get it". At any rate, this is likely going to be a hassle to fix. I'll probably need to create a timeout thread to wait for a logout or give up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant