/// <summary> /// Sends the message to the remote host. /// Returns a response if the corresponding Security Session is established and the initial message is not one-way. /// </summary> /// <param name="message">Message to be sent or a null reference (if there is a queued message).</param> protected override void InternalSend(Message message) { SharedMemoryConnection sharedMemoryConnection = null; string uri = message.Recipient.Url; bool isServer = false; // get the connection lock (message.Recipient.PersistentConnectionEstablishingLock) { switch (message.Recipient.GenuinePersistentConnectionState) { case GenuinePersistentConnectionState.NotEstablished: if (message.Recipient.Url == null) { throw GenuineExceptions.Get_Send_DestinationIsUnreachable(message.Recipient.Uri); } message.Recipient.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Opened; break; case GenuinePersistentConnectionState.Accepted: isServer = true; uri = message.Recipient.Uri; break; } // if it's possible to establish a connection to the remote host if (!isServer) { sharedMemoryConnection = this._persistent[uri] as SharedMemoryConnection; if (sharedMemoryConnection == null) { // try to establish a persistent connection string remoteUri; int remoteHostUniqueIdentifier; sharedMemoryConnection = this.LowLevel_OpenConnection(message.Recipient, this.Local.Uri, out remoteUri, out remoteHostUniqueIdentifier); // update remote host info message.Recipient.UpdateUri(remoteUri, remoteHostUniqueIdentifier); sharedMemoryConnection.Remote = message.Recipient; sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionEstablished, null, null); // OK, connection established this._persistent[uri] = sharedMemoryConnection; this.Connection_InitiateReceiving(sharedMemoryConnection); } } else { // remote host is a client and if there is no connection to it, it's unreachable sharedMemoryConnection = this._persistent[uri] as SharedMemoryConnection; if (sharedMemoryConnection == null) { throw GenuineExceptions.Get_Send_DestinationIsUnreachable(message.Recipient.Uri); } } } this.SendSync(message, sharedMemoryConnection); }
/// <summary> /// Releases all resources related to the specified connection. /// </summary> /// <param name="exception">The reason.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void ConnectionFailed(Exception exception, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { sharedMemoryConnection.IsValid = false; // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.ConnectionFailed, exception, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Connection has failed."); } // unregister the connection if (sharedMemoryConnection.Remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Accepted) { this._persistent.Remove(sharedMemoryConnection.Remote.Uri); } else { this._persistent.Remove(sharedMemoryConnection.Remote.Url); } // release all resources this.ITransportContext.KnownHosts.ReleaseHostResources(sharedMemoryConnection.Remote, exception); sharedMemoryConnection.ReleaseUnmanagedResources(); sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null); } catch (Exception ex) { // LOG: if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Unexpected exception inside the SharedMemoryClientConnectionManager.ConnectionFailed method. Most likely, something must be fixed."); } } }
/// <summary> /// Accepts the incoming connection. /// </summary> /// <param name="shareName">The name of the share.</param> /// <param name="protocolVersion">The version of the protocol supported by the remote host.</param> internal void Connection_AcceptConnection(string shareName, byte protocolVersion) { try { // accept the connection string remoteUri = null; int remoteHostUniqueIdentifier; SharedMemoryConnection connection = this.LowLevel_AcceptConnection_1(shareName, this.Local.Uri, protocolVersion, out remoteUri, out remoteHostUniqueIdentifier); connection.Remote = this.ITransportContext.KnownHosts[remoteUri]; connection.Remote.ProtocolVersion = protocolVersion; connection.Remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Accepted; connection.Remote.UpdateUri(remoteUri, remoteHostUniqueIdentifier); this._persistent[remoteUri] = connection; connection.SignalState(GenuineEventType.GeneralConnectionEstablished, null, null); // and process incoming messages this.Connection_InitiateReceiving(connection); } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.Connection_AcceptConnection", LogMessageType.ConnectionEstablished, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The connection from the remote host \"{0}\" has been refused.", shareName); } this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerFailure, ex, null, shareName)); } }
/// <summary> /// Releases all resources related to the specified connection. /// </summary> /// <param name="exception">The reason.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void ConnectionFailed(Exception exception, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { sharedMemoryConnection.IsValid = false; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.ConnectionFailed, exception, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Connection has failed."); } // unregister the connection if (sharedMemoryConnection.Remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Accepted) this._persistent.Remove(sharedMemoryConnection.Remote.Uri); else this._persistent.Remove(sharedMemoryConnection.Remote.Url); // release all resources this.ITransportContext.KnownHosts.ReleaseHostResources(sharedMemoryConnection.Remote, exception); sharedMemoryConnection.ReleaseUnmanagedResources(); sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null); } catch(Exception ex) { // LOG: if ( binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Unexpected exception inside the SharedMemoryClientConnectionManager.ConnectionFailed method. Most likely, something must be fixed."); } } }