private MessageContent.SessionInitMessageContent CreateNewSession_Internal(string remoteIpAddress, string remoteHostname, int remoteHandshakePort) { //attempt lock bool tryLock = lockSection.WaitOne(60000); if (!tryLock) throw new TimeoutException("[" + _description + "-M] Could not obtain lock while creating new session]"); try { //check if session already exists if (_tcpSessions.ContainsKey(remoteIpAddress)) { _evtRaiser.RaiseEvent("SessionError", "Cannot create session: A session already exists for address [" + remoteIpAddress + "]", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); throw new Exception("[" + _description + "-M] Cannot create session: A session already exists for address [" + remoteIpAddress + "]"); } //create a new session TcpSession session = new TcpSession(_applicationName, _ipAddress, _portRangeMin, _portRangeMax, remoteIpAddress, remoteHostname, remoteHandshakePort, _evtConsumer, _utilsBus,_t2_SRL_ThreadStatus.NodeID); //start the receiver session.ReceiverStart(_applicationName + ".TcpSessionManager.CreateNewSession"); /*the session is now half-created*/ /*the remote session data will be added later when the remote makes it available*/ //get the port and return the ip and port info MessageContent.SessionInitMessageContent initMessage = new MessageContent.SessionInitMessageContent(_ipAddress, _hostname, _handshakePort, session.LocalPort); //initMessage.IpAddress = _ipAddress; //initMessage.Hostname = _hostname; //initMessage.HandshakePort = _handshakePort; //initMessage.SessionPort = session.LocalPort; //add session to the session list _tcpSessions.Add(remoteIpAddress, session); //return session initialization object return initMessage; } finally { //release lock lockSection.Release(); } }
public bool ReceivedHandshakeExistingSessionValidations(TcpSession existingSession , MessageContent.HandshakeMessageContent remoteServerData) { //check if hostname changed if (existingSession.RemoteHostname != remoteServerData.Hostname) { logger.Warn("[" + _description + "-T] Hostname changed for session [" + remoteServerData.IpAddress + "] from [" + existingSession.RemoteHostname + "] to [" + remoteServerData.Hostname + "]; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Hostname changed for session [" + remoteServerData.IpAddress + "] from [" + existingSession.RemoteHostname + "] to [" + remoteServerData.Hostname + "]; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if handshake port changed if (existingSession.RemoteHandshakePort != remoteServerData.HandshakePort) { logger.Warn("[" + _description + "-T] Handshake port changed for session [" + remoteServerData.IpAddress + "] from [" + existingSession.RemoteHandshakePort + "] to [" + remoteServerData.HandshakePort + "]; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake port changed for session [" + remoteServerData.IpAddress + "] from [" + existingSession.RemoteHandshakePort + "] to [" + remoteServerData.HandshakePort + "]; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session initialization is complete if (!existingSession.IsSessionInitReceived || !existingSession.IsSessionInitSent) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where initialization never completed; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where initialization never completed; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session contains message transmitter errors if (existingSession.Transmitter != null && existingSession.Transmitter.ThreadStatus.MessageErrorCount > 0) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where there are message transmitter errors; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where there are message transmitter errors; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session contains message receiver errors if (existingSession.Receiver != null && existingSession.Receiver.ThreadStatus.MessageErrorCount > 0) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where there are message receiver errors; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where there are message receiver errors; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session validations valid if (existingSession.SessionValidationFailedDate > DateTime.MinValue) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where session integrity validations failed; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where session integrity validations failed; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session transmitter thread health failed if (existingSession.Transmitter != null && existingSession.Transmitter.ThreadStatus.CalculateThreadHealthFailed()) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where session transmitter thread health failed; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where session transmitter thread health failed; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session receiver thread health failed if (existingSession.Receiver != null && existingSession.Receiver.ThreadStatus.CalculateThreadHealthFailed()) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where session receiver thread health failed; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where session receiver thread health failed; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session transmitter status is non-active if (existingSession.Transmitter != null && (existingSession.Transmitter.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_STOPPED || existingSession.Transmitter.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_SUSPENDED || existingSession.Transmitter.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_UNKNOWN || existingSession.Transmitter.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_FINALIZED)) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where session transmitter status is non-active; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where session transmitter status is non-active; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } //check if session receiver status is non-active if (existingSession.Receiver != null && (existingSession.Receiver .ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_STOPPED || existingSession.Receiver.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_SUSPENDED || existingSession.Receiver.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_UNKNOWN || existingSession.Receiver.ThreadStatus.Status == Niawa.Threading.ThreadStatus.STATUS_FINALIZED)) { logger.Warn("[" + _description + "-T] Handshake message received for session [" + remoteServerData.IpAddress + "] where session receiver status is non-active; invalidating existing session"); _evtRaiser.RaiseEvent("SessionError", "UdpReceiverListener: Handshake message received for session [" + remoteServerData.IpAddress + "] where session receiver status is non-active; invalidating existing session", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); return true; } return false; }
/// <summary> /// Execute session validation checks. /// This may result in a session being removed /// </summary> /// <param name="session"></param> private bool SessionValidationChecks(TcpSession session, string remoteIpAddress) { try { /* -----------------------------------------------------------------------------*/ /* Session validity check: Session initialization not received after 60 seconds */ if (session.SessionValidationFailedDate == DateTime.MinValue && !session.IsSessionInitReceived) { if (session.ThreadStatus.InitializedDate != DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.ThreadStatus.InitializedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 60) { //validation failed session.SessionValidationFailedDate = DateTime.Now; //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] validation failed: session initialization has not been received for 60 seconds"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] validation failed: session initialization has not been received for 60 seconds", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); } } else { //session initialization date isn't valid } } /* -----------------------------------------------------------------------------*/ /* Session validity check: Transmitter is null after 60 seconds */ if (session.SessionValidationFailedDate == DateTime.MinValue && session.Transmitter == null) { if (session.ThreadStatus.InitializedDate != DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.ThreadStatus.InitializedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 60) { //validation failed session.SessionValidationFailedDate = DateTime.Now; //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] validation failed: session transmitter is null after 60 seconds"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] validation failed: session transmitter is null after 60 seconds", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); } } else { //session initialization date isn't valid } } /* -----------------------------------------------------------------------------*/ /* Session validity check: Transmitter message error count > 0 */ if (session.SessionValidationFailedDate == DateTime.MinValue && session.Transmitter != null && session.Transmitter.ThreadStatus.MessageErrorCount > 0) { if (session.ThreadStatus.InitializedDate != DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.ThreadStatus.InitializedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 60) { //validation failed session.SessionValidationFailedDate = DateTime.Now; //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] validation failed: transmitter error count is greater than zero"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] validation failed: transmitter error count is greater than zero", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); } } else { //session initialization date isn't valid } } /* -----------------------------------------------------------------------------*/ /* Session validity check: Receiver is null after 60 seconds */ if (session.SessionValidationFailedDate == DateTime.MinValue && session.Receiver == null) { if (session.ThreadStatus.InitializedDate != DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.ThreadStatus.InitializedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 60) { //validation failed session.SessionValidationFailedDate = DateTime.Now; //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] validation failed: session receiver is null after 60 seconds"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] validation failed: session receiver is null after 60 seconds", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); } } else { //session initialization date isn't valid } } /* -----------------------------------------------------------------------------*/ /* Session validity check: Transmitter message error count > 0 */ if (session.SessionValidationFailedDate == DateTime.MinValue && session.Receiver != null && session.Receiver.ThreadStatus.MessageErrorCount > 0) { if (session.ThreadStatus.InitializedDate != DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.ThreadStatus.InitializedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 60) { //validation failed session.SessionValidationFailedDate = DateTime.Now; //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] validation failed: receiver error count is greater than zero"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] validation failed: receiver error count is greater than zero", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); } } else { //session initialization date isn't valid } } /****************************************************************************/ /* If 90 seconds passed since last session validity check, remove the session*/ if (session.SessionValidationFailedDate > DateTime.MinValue) { TimeSpan timespan = (DateTime.Now - session.SessionValidationFailedDate); double timePassed = 0; timePassed = timespan.TotalSeconds + 0.01; if (timePassed > 90) { //validation failed - remove the session logger.Warn("[" + _description + "-TSRL] Session [" + remoteIpAddress + "] integrity validations failed for 90 seconds; removing invalidated session"); _evtRaiser.RaiseEvent("SessionError", "Session [" + remoteIpAddress + "] integrity validations failed for 90 seconds; removing invalidated session", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); //remove session //RemoveSession(remoteIpAddress, true); return true; } } return false; } catch (Exception ex) { logger.Error("[" + _description + "-TSRL] Error while executing session validation checks: " + ex.Message + "]", ex); _evtRaiser.RaiseEvent("Error", "Error while executing session validation checks: " + ex.Message, null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID); _t2_SRL_ThreadStatus.ErrorCount += 1; return false; } }