internal override void BeginSendTo(BaseSocketConnection connection, byte[] buffer) { if (!Disposed) { BeginSend(connection, buffer, true); } }
public static byte[] GetPacketBuffer(BaseSocketConnection connection, byte[] buffer, ref int bufferSize) { byte[] result = null; buffer = CryptUtils.EncryptData(connection, buffer); switch (connection.Context.DelimiterType) { case DelimiterType.dtNone: //----- No Delimiter! bufferSize = buffer.Length; result = connection.Context.Host.Context.BufferManager.TakeBuffer(bufferSize); Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length); break; case DelimiterType.dtMessageTailExcludeOnReceive: case DelimiterType.dtMessageTailIncludeOnReceive: if (connection.Context.Delimiter != null && connection.Context.Delimiter.Length >= 0) { //----- Need delimiter! bufferSize = buffer.Length + connection.Context.Delimiter.Length; result = connection.Context.Host.Context.BufferManager.TakeBuffer(bufferSize); Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length); Buffer.BlockCopy(connection.Context.Delimiter, 0, result, buffer.Length, connection.Context.Delimiter.Length); } else { bufferSize = buffer.Length; result = connection.Context.Host.Context.BufferManager.TakeBuffer(bufferSize); Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length); } break; } return result; }
public static byte[] GetRawBufferWithTail(BaseSocketConnection connection, SocketAsyncEventArgs e, int position, int delimiterSize) { //----- Get Raw Buffer with Tail! byte[] result = null; if (connection.Context.DelimiterType == DelimiterType.dtMessageTailIncludeOnReceive) { result = new byte[position - e.Offset + 1]; } else { result = new byte[position - e.Offset + 1 - delimiterSize]; } Buffer.BlockCopy(e.Buffer, e.Offset, result, 0, result.Length); for (int i = 0; i < delimiterSize; i++) { e.Buffer[position - i] = 0; } return result; }
/// <summary> /// Encrypts the data. /// </summary> /// <param name="connection"> /// Connection information. /// </param> /// <param name="buffer"> /// Data to be encrypted. /// </param> /// <param name="signOnly"> /// Indicates is encrypt method only uses symmetric algoritm. /// </param> public static byte[] EncryptData(BaseSocketConnection connection, byte[] buffer) { byte[] result = null; if ( (connection.Context.EventProcessing == EventProcessing.epEncrypt) || (connection.Context.EventProcessing == EventProcessing.epProxy) || (connection.Context.Creator.Context.EncryptType == EncryptType.etSSL && connection.Context.Creator.Context.CompressionType == CompressionType.ctNone) || (connection.Context.Creator.Context.EncryptType == EncryptType.etNone && connection.Context.Creator.Context.CompressionType == CompressionType.ctNone) ) { result = buffer; } else { using (MemoryStream ms = new MemoryStream()) { CryptoStream cs = null; GZipStream gs = null; switch (connection.Context.Creator.Context.EncryptType) { case EncryptType.etNone: case EncryptType.etSSL: { break; } default: { cs = new CryptoStream(ms, connection.Context.Encryptor, CryptoStreamMode.Write); break; } } switch (connection.Context.Creator.Context.CompressionType) { case CompressionType.ctGZIP: { if (cs != null) { gs = new GZipStream(cs, CompressionMode.Compress, true); } else { gs = new GZipStream(ms, CompressionMode.Compress, true); } break; } } if (gs != null) { gs.Write(buffer, 0, buffer.Length); gs.Flush(); gs.Close(); } else { cs.Write(buffer, 0, buffer.Length); } if (cs != null) { cs.FlushFinalBlock(); cs.Close(); } result = ms.ToArray(); } } return result; }
internal abstract void BeginSendTo(BaseSocketConnection connectionTo, byte[] buffer);
/// <summary> /// Receive data from connetion. /// </summary> internal void BeginReceive(BaseSocketConnection connection) { if (Disposed || !connection.Active) return; byte[] readMessage = null; try { bool completedAsync = true; lock (connection.Context.SyncReadPending) { if (!connection.Context.ReadPending) { //----- if the connection is not receiving, start the receive! if (connection.Context.EventProcessing == EventProcessing.epUser) { readMessage = Context.BufferManager.TakeBuffer(Context.MessageBufferSize); } else { readMessage = Context.BufferManager.TakeBuffer(2048); } connection.ReadOV.SetBuffer(readMessage, 0, readMessage.Length); connection.ReadOV.UserToken = connection; if (connection.Context.Stream != null) { //----- Ssl! connection.Context.Stream.BeginRead(connection.ReadOV.Buffer, 0, readMessage.Length, new AsyncCallback(BeginReadCallbackSSL), connection); } else { completedAsync = connection.Context.SocketHandle.ReceiveAsync(connection.ReadOV); } connection.Context.ReadPending = true; } } if (!completedAsync) { BeginReadCallbackAsync(this, connection.ReadOV); } readMessage = null; } catch (SocketException soex) { if ((soex.SocketErrorCode == SocketError.ConnectionReset) || (soex.SocketErrorCode == SocketError.NotConnected) || (soex.SocketErrorCode == SocketError.ConnectionAborted) || (soex.SocketErrorCode == SocketError.Shutdown) || (soex.SocketErrorCode == SocketError.Disconnecting)) { connection.BeginDisconnect(); } else { FireOnException(connection, soex); } } catch (Exception ex) { FireOnException(connection, ex); } if (readMessage != null) { context.BufferManager.ReturnBuffer(readMessage); } }
internal void AddSocketConnection(BaseSocketConnection socketConnection) { if (!Disposed) { FSocketConnectionsSync.EnterWriteLock(); try { context.SocketConnections.Add(socketConnection.Context.ConnectionId, socketConnection); socketConnection.WriteOV.Completed += new EventHandler<SocketAsyncEventArgs>(BeginSendCallbackAsync); socketConnection.ReadOV.Completed += new EventHandler<SocketAsyncEventArgs>(BeginReadCallbackAsync); } finally { FSocketConnectionsSync.ExitWriteLock(); } } }
public int ReadMessageWithNoDelimiter(BaseSocketConnection connection, SocketAsyncEventArgs e, int readBytes) { byte[] rawBuffer = null; rawBuffer = BufferUtils.GetRawBuffer(connection, e.Buffer, readBytes); FireOnReceived(connection, rawBuffer); return 0; }
private bool InitializeConnectionProxy(BaseSocketConnection connection) { bool result = false; if (!Disposed) { if (connection.Context.Creator is SocketConnector) { if (((SocketConnector)connection.Context.Creator).ProxyInfo != null) { connection.Context.EventProcessing = EventProcessing.epProxy; result = true; } } } return result; }
internal BaseSocketConnection[] GetSocketConnections() { BaseSocketConnection[] items = null; if (!Disposed) { FSocketConnectionsSync.EnterReadLock(); try { items = new BaseSocketConnection[Context.SocketConnections.Count]; Context.SocketConnections.Values.CopyTo(items, 0); } finally { FSocketConnectionsSync.ExitReadLock(); } } return items; }
internal void FireOnException(BaseSocketConnection connection, Exception ex) { if (Disposed) return; if (connection == null) { context.SocketService.OnException(new ExceptionEventArgs(connection, ex)); } else { if (connection.Active) { try { context.SocketService.OnException(new ExceptionEventArgs(connection, ex)); } finally { } } } }
internal void FireOnConnected(BaseSocketConnection connection) { if (Disposed || !connection.Active) return; try { switch (connection.Context.EventProcessing) { case EventProcessing.epUser: context.SocketService.OnConnected(new ConnectionEventArgs(connection)); break; case EventProcessing.epEncrypt: OnConnected(connection); break; case EventProcessing.epProxy: OnConnected(connection); break; } } finally { // } }
internal void DisposeConnection(BaseSocketConnection connection) { if (!Disposed) { if (connection != null) { if (connection.WriteOV != null) { if (connection.WriteOV.Buffer != null) { context.BufferManager.ReturnBuffer(connection.WriteOV.Buffer); } } if (connection.ReadOV != null) { if (connection.ReadOV.Buffer != null) { context.BufferManager.ReturnBuffer(connection.ReadOV.Buffer); } } connection.Dispose(); } } }
public SocketRSACryptoProvider(BaseSocketConnection connection, byte[] buffer) { this.connection = connection; this.buffer = buffer; }
public AuthenticateCallbackData(BaseSocketConnection connection, SslStream stream, HostType hostType) { FConnection = connection; FStream = stream; FHostType = hostType; }
private void FireOnReceived(BaseSocketConnection connection, byte[] buffer) { if (Disposed || !connection.Active) return; try { switch (connection.Context.EventProcessing) { case EventProcessing.epUser: context.SocketService.OnReceived(new MessageEventArgs(connection, buffer, false)); break; case EventProcessing.epEncrypt: OnReceived(connection, buffer); break; case EventProcessing.epProxy: OnReceived(connection, buffer); break; } } finally { // } }
private void FireOnSent(BaseSocketConnection connection, bool sentByServer) { if (Disposed || !connection.Active) return; try { switch (connection.Context.EventProcessing) { case EventProcessing.epUser: context.SocketService.OnSent(new MessageEventArgs(connection, null, sentByServer)); break; case EventProcessing.epEncrypt: OnSent(connection); break; case EventProcessing.epProxy: OnSent(connection); break; } } finally { // } }
/// <summary> /// Initializes the connection /// </summary> /// <param name="connection"></param> internal virtual void InitializeConnection(BaseSocketConnection connection) { if (!Disposed) { switch (connection.Context.EventProcessing) { case EventProcessing.epNone: if (InitializeConnectionProxy(connection)) { FireOnConnected(connection); } else { if (InitializeConnectionEncrypt(connection)) { FireOnConnected(connection); } else { connection.Context.EventProcessing = EventProcessing.epUser; FireOnConnected(connection); } } break; case EventProcessing.epProxy: if (InitializeConnectionEncrypt(connection)) { FireOnConnected(connection); } else { connection.Context.EventProcessing = EventProcessing.epUser; FireOnConnected(connection); } break; case EventProcessing.epEncrypt: connection.Context.EventProcessing = EventProcessing.epUser; FireOnConnected(connection); break; } } }
private void ReadFromConnection(BaseSocketConnection connection, int readBytes) { bool onePacketFound = false; int remainingBytes = 0; SocketAsyncEventArgs e = connection.ReadOV; switch (connection.Context.DelimiterType) { case DelimiterType.dtNone: //----- Message with no delimiter! remainingBytes = ReadMessageWithNoDelimiter(connection, e, readBytes); break; case DelimiterType.dtMessageTailExcludeOnReceive: case DelimiterType.dtMessageTailIncludeOnReceive: //----- Message with tail! remainingBytes = ReadMessageWithTail(connection, e, readBytes, ref onePacketFound); break; } if (remainingBytes == 0) { e.SetBuffer(0, e.Buffer.Length); } else { if (!onePacketFound) { e.SetBuffer(remainingBytes, e.Buffer.Length - remainingBytes); } else { byte[] readMessage = connection.Context.Host.Context.BufferManager.TakeBuffer(Context.MessageBufferSize); Buffer.BlockCopy(e.Buffer, e.Offset, readMessage, 0, remainingBytes); connection.Context.Host.Context.BufferManager.ReturnBuffer(e.Buffer); e.SetBuffer(null, 0, 0); e.SetBuffer(readMessage, remainingBytes, readMessage.Length - remainingBytes); } } if (!connection.Active) return; bool completedAsync = true; if (connection.Context.Stream != null) { connection.Context.Stream.BeginRead(e.Buffer, 0, e.Count, new AsyncCallback(BeginReadCallbackSSL), connection); } else { completedAsync = connection.Context.SocketHandle.ReceiveAsync(e); } if (!completedAsync) { BeginReadCallbackAsync(this, e); } }
internal bool InitializeConnectionEncrypt(BaseSocketConnection connection) { bool result = false; if (!Disposed) { ICryptoService cryptService = connection.Context.Creator.Context.CryptoService; if ((cryptService != null) && (connection.Context.Creator.Context.EncryptType != EncryptType.etNone)) { connection.Context.EventProcessing = EventProcessing.epEncrypt; result = true; } } return result; }
public int ReadMessageWithTail(BaseSocketConnection connection, SocketAsyncEventArgs e, int readBytes, ref bool onePacketFound) { byte[] rawBuffer = null; byte[] delimiter = connection.Context.Delimiter; int delimiterSize = delimiter.Length; bool readPacket = false; bool packetFound = false; int remainingBytes = readBytes + e.Offset; int bufferLength = e.Buffer.Length; byte[] buffer = e.Buffer; int offsetToFind = 0; int offsetBuffer = e.Offset; do { rawBuffer = null; packetFound = false; readPacket = false; while (offsetToFind < bufferLength) { offsetToFind = Array.IndexOf<byte>(buffer, delimiter[0], offsetToFind); if (offsetToFind == -1) { packetFound = false; break; } else { if (delimiterSize == 1) { offsetToFind++; packetFound = true; break; } else { packetFound = true; for (int i = 1; i < delimiterSize; i++) { offsetToFind++; if (buffer[offsetToFind] != delimiter[i]) { packetFound = false; break; } } if (packetFound) { break; } } } } if (packetFound) { onePacketFound = true; rawBuffer = BufferUtils.GetRawBufferWithTail(connection, e, offsetToFind, delimiterSize); rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, Context.MessageBufferSize); offsetToFind += 1; remainingBytes -= (offsetToFind - e.Offset); e.SetBuffer(offsetToFind, bufferLength - offsetToFind); offsetBuffer = offsetToFind; FireOnReceived(connection, rawBuffer); if (remainingBytes == 0) { readPacket = false; } else { readPacket = true; } } else { readPacket = false; } } while (readPacket); return remainingBytes; }
/// <summary> /// Initializes the connection /// </summary> /// <param name="connection"></param> internal void OnConnected(BaseSocketConnection connection) { if (Disposed || !connection.Active) return; try { switch (connection.Context.EventProcessing) { case EventProcessing.epEncrypt: switch (connection.Context.Creator.Context.EncryptType) { case EncryptType.etRijndael: if (connection.Context.Host.Context.HostType == HostType.htClient) { ISocketSecurityProvider socketSecurityProvider = new SocketRSACryptoProvider(connection, null); MemoryStream m = socketSecurityProvider.EcryptForClient(); connection.BeginSend(m.ToArray()); } else { connection.BeginReceive(); } break; case EncryptType.etSSL: if (connection.Context.Host.Context.HostType == HostType.htClient) { //----- Get SSL items X509Certificate2Collection certs = null; string serverName = null; bool checkRevocation = true; connection.Context.Creator.Context.CryptoService.OnSSLClientAuthenticate(connection, out serverName, ref certs, ref checkRevocation); //----- Authenticate SSL! SslStream ssl = new SslStream(new NetworkStream(connection.Context.SocketHandle), true, new RemoteCertificateValidationCallback(connection.Context.Creator.ValidateServerCertificateCallback)); if (certs == null) { ssl.BeginAuthenticateAsClient(serverName, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient)); } else { ssl.BeginAuthenticateAsClient(serverName, certs, System.Security.Authentication.SslProtocols.Tls, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient)); } } else { //----- Get SSL items! X509Certificate2 cert = null; bool clientAuthenticate = false; bool checkRevocation = true; connection.Context.Creator.Context.CryptoService.OnSSLServerAuthenticate(connection, out cert, out clientAuthenticate, ref checkRevocation); //----- Authneticate SSL! SslStream ssl = new SslStream(new NetworkStream(connection.Context.SocketHandle)); ssl.BeginAuthenticateAsServer(cert, clientAuthenticate, System.Security.Authentication.SslProtocols.Default, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htServer)); } break; } break; case EventProcessing.epProxy: ProxyInfo proxyInfo = ((SocketConnector)connection.Context.Creator).ProxyInfo; IPEndPoint endPoint = ((SocketConnector)connection.Context.Creator).Context.RemotEndPoint; byte[] proxyBuffer = ProxyUtils.GetProxyRequestData(proxyInfo, endPoint); connection.BeginSend(proxyBuffer); break; } } catch (Exception ex) { FireOnException(connection, ex); } }
/// <summary> /// Begin disconnect the connection /// </summary> internal void BeginDisconnect(BaseSocketConnection connection) { if (Disposed && !connection.Active) return; try { SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.Completed += new EventHandler<SocketAsyncEventArgs>(BeginDisconnectCallbackAsync); e.UserToken = connection; if (!connection.Context.SocketHandle.DisconnectAsync(e)) { BeginDisconnectCallbackAsync(this, e); } } catch (Exception ex) { FireOnException(connection, ex); } }
internal void OnReceived(BaseSocketConnection connection, byte[] buffer) { if (Disposed || !connection.Active) return; try { ISocketSecurityProvider socketSecurityProvider = new SocketRSACryptoProvider(connection, buffer); switch (connection.Context.EventProcessing) { case EventProcessing.epEncrypt: if (connection.Context.Host.Context.HostType == HostType.htServer) { //----- Deserialize authentication message try { MemoryStream m = socketSecurityProvider.DecryptForServer(); BeginSend(connection, m.ToArray(), false); } catch (SymmetricAuthenticationException ex) { FireOnException(connection, ex); } } else { //----- Deserialize authentication message try { AuthMessage am = socketSecurityProvider.DecryptForClient(); } catch (SymmetricAuthenticationException ex) { FireOnException(connection, ex); } } break; case EventProcessing.epProxy: ProxyInfo proxyInfo = ((SocketConnector)connection.Context.Creator).ProxyInfo; ProxyUtils.GetProxyResponseStatus(proxyInfo, buffer); if (proxyInfo.Completed) { InitializeConnection(connection); } else { IPEndPoint endPoint = ((SocketConnector)connection.Context.Creator).Context.RemotEndPoint; byte[] proxyBuffer = ProxyUtils.GetProxyRequestData(proxyInfo, endPoint); connection.BeginSend(proxyBuffer); } break; } } catch (Exception ex) { FireOnException(connection, ex); } }
/// <summary> /// Begin send the data. /// </summary> internal void BeginSend(BaseSocketConnection connection, byte[] buffer, bool sentByServer) { if (Disposed || !connection.Active) return; byte[] sendBuffer = null; try { if ((connection.Context.EventProcessing == EventProcessing.epUser) && (buffer.Length > Context.MessageBufferSize)) { throw new MessageLengthException("Message length is greater than Host maximum message length."); } bool completedAsync = true; int bufferSize = 0; sendBuffer = BufferUtils.GetPacketBuffer(connection, buffer, ref bufferSize); lock (connection.Context.WriteQueue) { if (connection.Context.WriteQueueHasItems) { //----- If the connection is sending, enqueue the message! MessageBuffer message = new MessageBuffer(sendBuffer, bufferSize, sentByServer); connection.Context.WriteQueue.Enqueue(message); } else { connection.WriteOV.SetBuffer(sendBuffer, 0, bufferSize); connection.WriteOV.UserToken = new WriteData(connection, sentByServer); //----- If the connection is not sending, send the message! if (connection.Context.Stream != null) { //----- Ssl! connection.Context.Stream.BeginWrite(connection.WriteOV.Buffer, 0, bufferSize, new AsyncCallback(BeginSendCallbackSSL), new WriteData(connection, sentByServer)); } else { //----- Socket! completedAsync = connection.Context.SocketHandle.SendAsync(connection.WriteOV); } connection.Context.WriteQueueHasItems = true; } } sendBuffer = null; if (!completedAsync) { BeginSendCallbackAsync(this, connection.WriteOV); } } catch (SocketException soex) { if ((soex.SocketErrorCode == SocketError.ConnectionReset) || (soex.SocketErrorCode == SocketError.ConnectionAborted) || (soex.SocketErrorCode == SocketError.NotConnected) || (soex.SocketErrorCode == SocketError.Shutdown) || (soex.SocketErrorCode == SocketError.Disconnecting)) { connection.BeginDisconnect(); } else { FireOnException(connection, soex); } } catch (Exception ex) { FireOnException(connection, ex); } if (sendBuffer != null) { Context.BufferManager.ReturnBuffer(sendBuffer); } }
internal void OnSent(BaseSocketConnection connection) { if (Disposed || connection.Active) return; try { switch (connection.Context.EventProcessing) { case EventProcessing.epEncrypt: if (connection.Context.Host.Context.HostType == HostType.htServer) { connection.Context.EventProcessing = EventProcessing.epUser; FireOnConnected(connection); } else { connection.BeginReceive(); } break; case EventProcessing.epProxy: connection.BeginReceive(); break; } } catch (Exception ex) { FireOnException(connection, ex); } }
internal void CloseConnection(BaseSocketConnection connection) { if (!Disposed) { connection.Active = false; connection.Context.SocketHandle.Shutdown(SocketShutdown.Send); lock (connection.Context.WriteQueue) { if (connection.Context.WriteQueue.Count > 0) { for (int i = 1; i <= connection.Context.WriteQueue.Count; i++) { MessageBuffer message = connection.Context.WriteQueue.Dequeue(); if (message != null) { Context.BufferManager.ReturnBuffer(message.Buffer); } } } } } }
internal void RemoveSocketConnection(BaseSocketConnection socketConnection) { if (!Disposed) { if (socketConnection != null) { FSocketConnectionsSync.EnterWriteLock(); try { context.SocketConnections.Remove(socketConnection.Context.ConnectionId); } finally { if (context.SocketConnections.Count <= 0) { fWaitConnectionsDisposing.Set(); } FSocketConnectionsSync.ExitWriteLock(); } } } }
/// <summary> /// Decrypts the data. /// </summary> /// <param name="connection"> /// Connection information. /// </param> /// <param name="buffer"> /// Data to be encrypted. /// </param> /// <param name="maxBufferSize"> /// Max buffer size accepted. /// </param> public static byte[] DecryptData(BaseSocketConnection connection, byte[] buffer, int maxBufferSize) { byte[] result = null; if ( (connection.Context.EventProcessing == EventProcessing.epEncrypt) || (connection.Context.EventProcessing == EventProcessing.epProxy) || (connection.Context.Creator.Context.EncryptType == EncryptType.etSSL && connection.Context.Creator.Context.CompressionType == CompressionType.ctNone) || (connection.Context.Creator.Context.EncryptType == EncryptType.etNone && connection.Context.Creator.Context.CompressionType == CompressionType.ctNone) ) { result = buffer; } else { MemoryStream ms = new MemoryStream(buffer); CryptoStream cs = null; GZipStream gs = null; switch (connection.Context.Creator.Context.EncryptType) { case EncryptType.etNone: case EncryptType.etSSL: { break; } default: { cs = new CryptoStream(ms, connection.Context.Decryptor, CryptoStreamMode.Read); break; } } switch (connection.Context.Creator.Context.CompressionType) { case CompressionType.ctGZIP: { if (cs != null) { gs = new GZipStream(cs, CompressionMode.Decompress, true); } else { gs = new GZipStream(ms, CompressionMode.Decompress, true); } break; } } BinaryReader b = null; if (gs != null) { b = new BinaryReader(gs); } else { b = new BinaryReader(cs); } result = b.ReadBytes(maxBufferSize); b.Close(); } return result; }
private void FireOnDisconnected(BaseSocketConnection connection) { if (Disposed) return; try { context.SocketService.OnDisconnected(new ConnectionEventArgs(connection)); } finally { } }