//Shahbaz Chaudhary //shahbazc gmail com //Persistent variables (survive session crash) expectedInSeqNum = 1 expectedOutSeqNum = 1 (assume automatically set) //Session level variables (do not survive session crash) isLoggedIn = false; isResendRequested = false; timeOfLastIn = none timeOfLastOut = none (assume automatically set) sender = nothing target = nothing version = nothing msg = valid message arrives timeOfLastIn = now //==================INCOMING============================= //-------------FRAME DECODING & MSG VALIDATION----------------------------- decode frame if checksum not matches ignore msg warn "corrupt msg, checksum didn't match" //-------------LOGON PROCSSING (acceptor)----------------------------- //first message must be logon [initiator and acceptor behave differently] if not isLoggedIn if msg is not [logon] ignore msg error "first message must be [logon]" disconnect connection else msg is [logon] if isAcceptor isAuth = authenticate(msg,remoteIP) //potentially blocking if isLoggedIn = true; initSession{ sender = msg[senderCompID] target = msg[targetCompID] version = msg[version] archiveMsgs = getOldSession(version,sender,target) //potenetially blocking expectedInSeqnum = getExectedIn(archiveMsgs) expectedOutSeqnum = getExectedOut(archiveMsgs) } scheduleTimer{ every heartBeatInt seconds call if (now - timeOfLastOut) > heartBeatInt send [heartbeat] if (now - timeOfLastIn) > heartBeatInt send [test request] if (now - timeOfLastIn) > (1.5 * heartBeantInt) error "no heartbeats from counter party, time to die" disconnect session } send [logon ack] else ignore msg error "unknown connection" disconnect connection else isInitiator isLoggedIn = true; //initSession is done when logon msg is being sent scheduleTimer{ every heartBeatInt seconds call if (now - timeOfLastOut) > heartBeatInt send [heartbeat] if (now - timeOfLastIn) > heartBeatInt send [test request] if (now - timeOfLastIn) > (1.5 * heartBeantInt) error "no heartbeats from counter party, time to die" disconnect session } //-------------COMMON SESSION PROCSSING----------------------------- //record msg (needed for resend request) record msg //duplicate logon (CORRECTION: check this in logon logic) if isLoggedIn and msg is [logon] ignore msg error "already logged in" send [session reject] if msg is [sequence-reset] and gap-fill is undefined or N if newseqnum >= expectedInSeqNum expectedInSeqNum = newseqnum else ignore msg error "can't reduce seqnums! manual intervention needed" disconnect connection //check seqnums if inSeqNum = expectedInSeqNum increment expectedInSeqNum isResendRequested = false else if inSeqNum < expectedInSeqNum and posdup is Y ignore msg else if inSeqNum < expectedInSeqNum and posdup is undefined or N ignore msg error "manual intervention needed!" send [logout] with error reason disconnect connection else if inSeqNum > expectedInSeqNum ignore msg if msg is [resend-request] (CONFUSION: check this against spec) for list of requested messages from record if msg is [logon, logout, resendreq, heartbeat, testreq, seqreset] send [seq-reset] with gap-fill Y send msg with posdup = Y if isResendRequested is false isResendRequested = true send [resend-request] for missing messages if msg is [sequence-reset] and gap-fill is Y if newseqnum >= expectedInSeqNum expectedinSeqNum = newseqnum else ignore msg error "can't reduce seqnums! manual intervention needed" disconnect connection //check compids and version if sender, target or version don't match ignore msg error "sender, target and version must match logon" send [session-reject] //real session logic //[initiator and acceptor behave differently] if msg is [logout] send [logout ack] if msg is [test request] send [heartbeat] with test request id if msg is [resend request] for list of requested messages from record if msg is [logon, logout, resendreq, heartbeat, testreq, seqreset] send [seq-reset] with gap-fill Y send msg with posdup = Y //==================OUTGOING============================= fix-string = converToFIX(fix-map, version, sender, target, timestamp, seqnum) increment outgoing seqnum send fix-string