QuickFIX/J cannot logon after TestRequest - fix-protocol

Summary
I have an initiator with quickfix 50sp2 on a FIXT1.1 transport layer. As I see in the log messages, there is no connection problem. Heartbeats are reaching to each side. But randomly my initiator sends test request to acceptor even if it gets heartbeat as expected. Acceptor response to test request with a heartbeat including TestReqID. After that my initiator sends logon messages. Acceptor sends logon too and then loop starts. If I restart the whole application, initiator can logon and gets heartbeat.
Expectation
After acceptor sends heartbeat with specific TestReqID, I'm expecting that getting and sending heartbeats. Instead, initiator is sending logon message and not loggin' to the acceptor.
Event.Log
20220719-01:01:05: Initiated logon request
20220719-01:01:05: Setting DefaultApplVerID (1137=9) from Logon
20220719-01:01:05: Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
20220719-01:01:05: Received logon
20220719-09:00:17: Sent test request TEST
20220719-09:00:29: Disconnecting: Timed out waiting for heartbeat
20220719-09:00:33: Pending connection not established after 4001 ms.
20220719-09:00:36: Pending connection not established after 7002 ms.
20220719-09:00:36: MINA session created: local=/hosti:porti, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/hosta:porta
20220719-09:00:37: Initiated logon request
20220719-09:00:37: Setting DefaultApplVerID (1137=9) from Logon
20220719-09:00:48: Disconnecting: Timed out waiting for logon response
20220719-09:01:29: MINA session created: local=/hosti:porti, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/hosta:porta
20220719-09:01:30: Initiated logon request
20220719-09:01:30: Setting DefaultApplVerID (1137=9) from Logon
20220719-09:01:40: Disconnecting: Timed out waiting for logon response
20220719-09:02:29: MINA session created: local=/hosti:porti, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/hosta:porta
Messages.log
8=FIXT.1.19=00005235=049=ACCEPTOR56=INITIATOR34=98952=20220719-08:58:46.53810=079
8=FIXT.1.19=6135=034=95749=INITIATOR50=SNDRSUBID52=20220719-08:59:05.15856=ACCEPTOR10=107
8=FIXT.1.19=00041535=849=ACCEPTOR56=INITIATOR34=99052=20220719-08:59:16.22737=ORDID11=NONE453=3448=GL-P447=D452=28448=INITIATOR447=D452=1448=KL305447=D452=12880=TRDMTCHID17=1234567150=F39=221100=1.000000021101=1.000000055=EURUSD48=17107122=M54=138=1.000000040=244=1.000000059=0528=P32=1.000000031=1.0000000151=014=1.00000006=060=20220719-08:59:16.226797=Y10=090
8=FIXT.1.19=00052135=AE49=ACCEPTOR56=INITIATOR34=99152=20220719-08:59:16.23220008=1.000000021100=1.000000021102=123420017=020018=1.0000000730=1.0000000571=90063491003=123456:123A487=0856=0829=1001855=1880=TRDMTCHID570=N55=EURUSD48=17107122=M38=1.000000032=1.000000031=1.000000075=20220719715=2022071960=20220719-08:59:16.000573=0552=154=137=ORDID453=3448=INITIATOR447=D452=1448=GL-P447=D452=28448=KL305447=D452=12528=P1057=N797=Y1703=11704=1000000010=054
8=FIXT.1.19=6135=034=95849=INITIATOR50=SNDRSUBID52=20220719-08:59:35.15856=ACCEPTOR10=111
8=FIXT.1.19=00005235=049=ACCEPTOR56=INITIATOR34=99252=20220719-08:59:46.59010=072
8=FIXT.1.19=6135=034=95949=INITIATOR50=SNDRSUBID52=20220719-09:00:05.15856=ACCEPTOR10=096
8=FIXT.1.19=00005235=049=ACCEPTOR56=INITIATOR34=99352=20220719-09:00:16.65910=063
8=FIXT.1.19=7035=134=96049=INITIATOR50=SNDRSUBID52=20220719-09:00:17.15856=ACCEPTOR112=TEST10=110
8=FIXT.1.19=00006135=049=ACCEPTOR56=INITIATOR34=99452=20220719-09:00:17.163112=TEST10=073
8=FIXT.1.19=12435=A34=149=INITIATOR50=SNDRSUBID52=20220719-09:00:37.15956=ACCEPTOR98=0108=30141=Y553=USERNAME554=PASSWORD1137=91409=010=083
8=FIXT.1.19=00009135=A49=ACCEPTOR56=INITIATOR34=152=20220719-09:00:37.17820002=2698=0108=30141=Y1409=01137=910=061
8=FIXT.1.19=12435=A34=149=INITIATOR50=SNDRSUBID52=20220719-09:01:30.15856=ACCEPTOR98=0108=30141=Y553=USERNAME554=PASSWORD1137=91409=010=076
8=FIXT.1.19=00009135=A49=ACCEPTOR56=INITIATOR34=152=20220719-09:01:30.17520002=2698=0108=30141=Y1409=01137=910=052
8=FIXT.1.19=12435=A34=149=INITIATOR50=SNDRSUBID52=20220719-09:02:30.15856=ACCEPTOR98=0108=30141=Y553=USERNAME554=PASSWORD1137=91409=010=077
8=FIXT.1.19=00009135=A49=ACCEPTOR56=INITIATOR34=152=20220719-09:02:30.17520002=2698=0108=30141=Y1409=01137=910=053
What I've Tried
Added TestRequestDelayMultiplier = 1 to the session properties.
Found this topic it looks relative but there is no answer.
session.properties
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60
ResetOnLogon=Y
FileLogPath=logs/Client_Logs
SenderCompID=INITIATOR
SenderSubID=SNDRSUBID
ValidateIncomingMessage=N
TestRequestDelayMultiplier=1
[SESSION]
BeginString=FIXT.1.1
TargetCompID=ACCEPTOR
StartDay=sunday
EndDay=friday
StartTime=21:35:00
EndTime=21:30:00
HeartBtInt=30
CheckLatency=N
SocketConnectPort=port
SocketConnectHost=host
DefaultApplVerID=9
UseDataDictionary=Y
DataDictionary=config/cptyFIX50sp2.xml
FileStorePath=logs/Client_Seq_Store
TransportDataDictionary=config/FIXT11.xml
AppDataDictionary=config/cptyFIX50sp2.xml

I think the problem is that the counterparty does not reply to your TestRequest message with the full SessionID. Normally this is a combination of SenderCompID and TargetCompID.
However, in your settings you specify SenderSubID=SNDRSUBID but the counterparty does not include the SNDRSUBID on their messages. In my opinion they should send it back to you as TargetSubID.
Could you try to remove the SenderSubID from your settings and see if that works?
If you need the SenderSubID on some of your messages then please only set it programatically on selected messages and not for the complete session.

Related

How to work FIX session on VPN when we connect the apllication with FIX server

how the FIX Session works on VPN Tunnel and how many sessions should be created when we send the request on FIX.
my problem is that many session have created on VPN in one day i.e 30 000 session created so my FIX protocol does not respond properly,
how can I create only one session at a time?
This property file I used for FIX connectivity.
FileStorePath=data
ConnectionType=initiator
SenderCompID=XXX
TargetCompID=PSE
#SocketConnectHost=********
StartTime=09:30:00
Asia/Manila
EndTime=16:30:01
Asia/Manila
HeartBtInt=30
ReconnectInterval=50000
ResetOnLogon=Y
ResetOnLogout=Y
ResetOnDisconnect=Y
Username=*******
Password=*****
BeginString=FIXT.1.1
DefaultApplVerID=9
SocketConnectPort=xx
Session.lookupSession(sessionId).logout("user requested");
This function is get used for logging out.But gives the following error:
FIXIT.1.1:135->PSE, event> (Initiated logout response) FIXIT.1.1:135->PSE, event> (Disconnecting:Received logout response)
This are the logs that are shown on my console.
In the above the logout is done successfully and the session is removed from my side.But problem is that i didn't understand session is get destroyed or not? And if the session is destroyed then why VPN server is showing the connection is not destroyed? Is the problem from my side or there is a network issue?

How to force CoTURN long term credentials validation from WebRTC Flutter application?

I use this example of Flutter data channel to connect my Android app to my CoTURN server on my local network. The CoTURN logs show that the Android app connects successfully to the CoTURN server but doesn't show any username. I would like to make sure that no access is possible to my CoTURN server while not using long term credentials.
The version of my CoTURN server is 4.5.1.1-1.1 on Debian Linux Stable (10 Buster). The lt-cred-mech is already set in the CoTURN server configuration while no-auth is not set (it is commented). I am using verbose to check the logs. I have a user created in my MySQL database for long term credentials. It is verified using this command on the secured port:
turnutils_uclient -p 5349 -u myuser -w mypassword 192.168.188.28
It leads to the following in the coturn logs:
1992: handle_udp_packet: New UDP endpoint: local addr 192.168.188.28:5349, remote addr 192.168.188.28:58256
1992: session 002000000000000002: realm <myrealm> user <>: incoming packet message processed, error 401: Unauthorized
1992: IPv4. Local relay addr: 192.168.188.28:64632
1992: IPv4. Local reserved relay addr: 192.168.188.28:64633
1992: session 002000000000000002: new, realm=<myrealm>, username=<myuser>, lifetime=777
1992: session 002000000000000002: realm <myrealm> user <myuser>: incoming packet ALLOCATE processed, success
1992: session 002000000000000002: refreshed, realm=<myrealm>, username=<myuser>, lifetime=777
1992: session 002000000000000002: realm <myrealm> user <myuser>: incoming packet REFRESH processed, success
...
2007: session 003000000000000003: delete: realm=<myrealm>, username=<myuser>
2007: session 003000000000000003: peer 0.0.0.0:3481 deleted
2008: session 001000000000000008: usage: realm=<myrealm>, username=<myuser>, rp=13, rb=1360, sp=8, sb=768
2008: session 001000000000000008: closed (2nd stage), user <myuser> realm <myrealm> origin <>, local 192.168.188.28:5349, remote 192.168.188.28:48266, reason: allocation timeout
2008: session 001000000000000008: delete: realm=<myrealm>, username=<myuser>
2008: session 001000000000000008: peer 0.0.0.0:3481 deleted
If I try the same command with an intentionally invalid user, I get the expected following results in the server logs:
2227: handle_udp_packet: New UDP endpoint: local addr 192.168.188.28:5349, remote addr 192.168.188.28:40431
2227: session 002000000000000003: realm <myrealm> user <>: incoming packet message processed, error 401: Unauthorized
2227: check_stun_auth: Cannot find credentials of user <myuserfaulty>
2227: session 002000000000000003: realm <myrealm> user <myuserfaulty>: incoming packet message processed, error 401: Unauthorized
2227: check_stun_auth: Cannot find credentials of user <myuserfaulty>
...
So, this means that the credentials are indeed checked by the CoTURN server.
However, when I add credentials to the Flutter app as follows, I get server logs that don't seem to show any user. Worst, if the user is intentionally faulty, it changes nothing. Here is the portion of code adapted:
...
Map<String, dynamic> configuration = {
"iceServers": [
{"url": "stun:192.168.188.28:5349"},
{"username": "myuserfaulty"},
{"credential": "mypassword"},
]
};
...
Note that I guessed the username and credential entries in the configuration from the following files:
https://github.com/cloudwebrtc/flutter-webrtc/blob/master/ios/Classes/FlutterWebRTCPlugin.m
https://github.com/cloudwebrtc/flutter-webrtc/blob/master/android/src/main/java/com/cloudwebrtc/webrtc/FlutterWebRTCPlugin.java
Here are the CoTURN logs while using intentionally wrong credentials from Flutter:
2945: handle_udp_packet: New UDP endpoint: local addr 192.168.188.28:5349, remote addr 192.168.188.31:58350
2945: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
2955: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
2965: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
2975: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
2985: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
2995: session 002000000000000004: realm <myrealm> user <>: incoming packet BINDING processed, success
3005: session 002000000000000004: usage: realm=<myrealm>, username=<>, rp=6, rb=120, sp=6, sb=528
3005: session 002000000000000004: closed (2nd stage), user <> realm <myrealm> origin <>, local 192.168.188.28:5349, remote 192.168.188.31:58350, reason: allocation watchdog determined stale session state
3005: handle_udp_packet: New UDP endpoint: local addr 192.168.188.28:5349, remote addr 192.168.188.31:58350
3005: session 002000000000000005: realm <myrealm> user <>: incoming packet BINDING processed, success
3015: session 002000000000000005: realm <myrealm> user <>: incoming packet BINDING processed, success
...
So, I have the following questions:
How can I make sure that my CoTURN server cannot be used without authorized long term credentials?
How come the Flutter app is not subject to the same credentials validation as the turnutils_uclient?
Did I guess correctly the way to specify the credentials in the Flutter app with the addition of the username and credential entries in the configuration?
With this configuration (lt-cred-mech), the TURN server cannot be used without authorized long term credentials. However, the STUN server never requires authentication.
The turnutils_uclient command requires authentication because it calls the TURN server. To make a STUN server test call, the turnutils_stunclient command can be used and no credentials can be given to it.
The format for long term authentication on TURN server in Flutter is described in a comment in this file:
https://github.com/cloudwebrtc/flutter-webrtc-demo/blob/master/lib/src/call_sample/signaling.dart
...
{
'url': 'turn:123.45.67.89:3478',
'username': 'change_to_real_user',
'credential': 'change_to_real_secret'
},
...
which shows that my attempts were wrong for two reasons:
The protocol must be set to turn instead of stun.
The configuration items must be in the same array.
After those corrections, I do get the username in the coturn server logs as shown below:
87055: session 000000000000000540: new, realm=<myrealm>, username=<myuser>, lifetime=600
87055: session 000000000000000540: realm <myrealm> user <myuser>: incoming packet ALLOCATE processed, success
87065: session 000000000000000540: realm <myrealm> user <myuser>: incoming packet BINDING processed, success
Note that the coturn server configuration can require authentication for the STUN binding request as well:
...
# Require authentication of the STUN Binding request.
# By default, the clients are allowed anonymous access to the STUN Binding functionality.
#
#secure-stun
...

QuickFIX Initiator sends logout request and does not reconnect

I am using a FIX session to get TradeCaptureReports. When connection is established, I get responses to TradeCaptureRequest. After logon, heartbeat messages are sending and receiving.
But then FIX initiator sends logout request and does not reconnect, even if ReconnectInterval is set to 1 in session config.
event log:
08:23:56 : Initiated logon request
08:23:56 : Logon contains ResetSeqNumFlag=Y, reseting sequence numbers to 1
08:23:56 : Received logon response
08:25:42 : Initiated logout request
I need to keep QuickFIX connection alive and keep sending scheduled TradeCaptureRequests. Do you have any idea, what can cause this logout?
Message log after logon request and response:
8=FIX.4.4|9=56|35=0|34=3|49=**|52=20151203-08:24:56.310|56=***|10=169|
8=FIX.4.4|9=56|35=0|49=***|56=**|34=3|52=20151203-08:24:55.771|10=179|
8=FIX.4.4|9=56|35=0|34=4|49=**|52=20151203-08:25:26.313|56=***|10=171|
8=FIX.4.4|9=56|35=0|49=***|56=**|34=4|52=20151203-08:25:25.772|10=179|
8=FIX.4.4|9=56|35=5|34=5|49=**|52=20151203-08:25:42.338|56=***|10=182|
Session Config:
HeartBtInt=30
ReconnectInterval=1
ResetOnLogon=Y
StartTime=00:00:00
EndTime=00:00:00
I won't be able to test this until Monday, but I don't think you can set your StartTime to be equal to your EndTime. That would explain why it's disconnecting, because it doesn't think it's time for the session to be up.
QuickFix does support week long sessions, if you use the StartDay and EndDay parameters, in conjunction with the StartTime and EndTime ones.

quickfix sends logout in response to logon

I have a FIX server and client implemented using quickfix v1.14.3. When the client sends a logon request, the server immediately sends a logout message.There is nothing in the logs to indicate why it is so. The SenderCompID and TargetCompID both match between the server and client. I have removed the previous sessions states on both the server and client. Is there any way to find why the server is sending the logout message?
Here is the server configuration
enter code here
[DEFAULT]
ConnectionType=acceptor
ReconnectInterval=60
FileStorePath=/temp/quickfix/mktdata
SocketAcceptPort=32323
SocketReuseAddress=Y
SenderCompID=Server1
[SESSION]
BeginString=FIX.4.4
TargetCompID=INCA
StartTime=00:30:00
EndTime=21:30:00
ReconnectInterval=30
HeartBtInt=30
SocketConnectPort=6523
SocketConnectHost=0.0.0.0
DataDictionary=/opt/quickfix/spec/FIX44.xml
Here is the client configuration
[DEFAULT]
ConnectionType=initiator
HeartBtInt=30
ReconnectInterval=1
FileStorePath=/temp/quickfix/order
StartTime=00:00:00
EndTime=00:00:00
SocketConnectHost=localhost
UseDataDictionary=Y
SenderCompID=INCA
DataDictionary=/opt/quickfix/spec/FIX44.xml
[SESSION]
BeginString=FIX.4.4
TargetCompID=Server1
SocketConnectPort=32323
Answering from the comments, it's a start time/end time issue.
I think it may be due to StartTime/EndTime. My problems occurred in the evening when the time is past the EndTime(UTC).– RamJul 27 at 13:13
Your problem looks like problem of not matching StartTime and EndTime settings of the Acceptor and the Initiator. However, if you like find out more, implement IApplicationExt instead of IApplication, and in the section where you override the IApplication interface functions, override also FromEarlyIntercept and test msg for "is Logout":
public void FromEarlyIntercept(Message msg, SessionID sessionID)
{
string msgText = msg.GetField(Tags.Text);
if (msg is Logout)
{
Console.WriteLine(" Connection of Session {0} forced to logout, because: {1}", sessionID, msgText);
}
There in the respective Logout tags content you may find the explanation for your LogOut. I hope this helps.

QuickFix/N sending repeated logons

I use QuickFixN to connect to 2 liquidity providers.
One is connecting and working fine. The other isn't showing any error message, seems to be connecting, but Logon isn't succeeding.
In the messages log: I am sending the Logon request (message type 'A'), and receiving back another message type A, but then nothing happens. 30secs later this happens again. It has many repeats looking like this:
20131118-20:11:32.422 : 8=FIX.4.49=11535=A34=149=XXXX50=XXXX52=20131118-20:11:32.40856=XXXX57=XXXX98=0108=30141=Y10=152
20131118-20:11:32.795 : 8=FIX.4.49=11535=A34=149=XXXX50=XXXX52=20131118-20:11:32.61956=XXXX57=XXXX98=0108=30141=Y10=156
....same again every 30secs....
the event log looks like this:
20131118-20:11:32.023 : Connecting to AA.AAA.AAA.AAA on port BBBB
20131118-20:11:32.395 : Connection succeeded
20131118-20:11:32.408 : Session reset: ResetOnLogon
20131118-20:11:32.422 : Session reset: ResetSeqNumFlag
20131118-20:11:32.422 : Initiated logon request
20131118-20:11:32.796 : Message 1 Rejected: 9
20131118-20:11:32.798 : Verify failed: Tried to send a reject while not logged on
20131118-20:11:32.798 : Session FIX.4.4:XXXX->YYYY disconnecting: Verify failed: Tried to send a reject while not logged on
Within my application, on the QuickFix.Application interface, OnCreate is being called for this session, and so is OnLogout, but OnLogon is not. Neither FromAdmin or FromApp receive any messages from this session.
What could I be doing wrong?
The "Message 1 Rejected: 9" phrase is saying the message with sequence number 1 (the Logon message) was rejected for reason 9. The reason is a FIX Session Reject Reason and 9 indicates a CompID problem. Double-check your sender and target CompIDs in the message to be sure they are correct for your counterparty. Note that your side of the session is rejecting their login so it could be an issue with configuration of your session. The "Verify failed" message is logged because QuickFIX/n is apparently trying to send a reject message before the session is logged in.