private void Disconnect_Completed(Socket socket, ServerAsyncEventArgs e) { for (; ;) { int backlog = Thread.VolatileRead(ref acceptBacklog); if (isRunning && backlog < maxAcceptBacklog) { if (Interlocked.CompareExchange(ref acceptBacklog, backlog + 1, backlog) == backlog) { e.AcceptSocket = socket; try { listener.AcceptAsync(e, Accept_Completed); } catch { EventArgsManager.Put(e); } break; } } else { EventArgsManager.Put(e); break; } } }
private void Accept_Completed(Socket none, ServerAsyncEventArgs e) { Socket acceptSocket = e.AcceptSocket; SocketError error = e.SocketError; for (; ;) { int backlog = Thread.VolatileRead(ref acceptBacklog); if (isRunning && backlog <= minAcceptBacklog) { e.AcceptSocket = null; listener.AcceptAsync(e, Accept_Completed); break; } else { if (Interlocked.CompareExchange(ref acceptBacklog, backlog - 1, backlog) == backlog) { EventArgsManager.Put(e); break; } } } var connection = CreateConnection(acceptSocket, error); if (connection != null) { NewTcpConnection(connection); } }
private void Disconnect_Completed(Socket socket, ServerAsyncEventArgs e) { int num; do { num = Thread.VolatileRead(ref this.acceptBacklog); if (!this.isRunning || num >= this.maxAcceptBacklog) { goto IL_5B; } }while (Interlocked.CompareExchange(ref this.acceptBacklog, num + 1, num) != num); e.AcceptSocket = socket; try { this.listener.AcceptAsync(e, new ServerAsyncEventArgs.CompletedEventHandler(this.Accept_Completed)); return; } catch { EventArgsManager.Put(e); return; } IL_5B: EventArgsManager.Put(e); }
private void Accept_Completed(Socket none, ServerAsyncEventArgs e) { Socket acceptSocket = e.AcceptSocket; SocketError socketError = e.SocketError; while (true) { int num = Thread.VolatileRead(ref this.acceptBacklog); if (this.isRunning && num <= this.minAcceptBacklog) { break; } if (Interlocked.CompareExchange(ref this.acceptBacklog, num - 1, num) == num) { goto Block_3; } } e.AcceptSocket = null; this.listener.AcceptAsync(e, new ServerAsyncEventArgs.CompletedEventHandler(this.Accept_Completed)); goto IL_66; Block_3: EventArgsManager.Put(e); IL_66: Server <C> .Connection <C> connection = this.CreateConnection(acceptSocket, socketError); if (connection != null) { this.NewTcpConnection(connection); } }
private bool TcpReceiveAsync(Connection <C> connection, ServerAsyncEventArgs e) { PrepareEventArgs(connection, e); try { connection.SpinLock.Enter(); e.SequenceNumber = connection.ReceiveQueue.SequenceNumber; try { if (connection.IsClosed == false) { bool result = connection.Socket.ReceiveAsync(e); connection.ReceiveQueue.SequenceNumber++; return(result); } } finally { connection.SpinLock.Exit(); } } catch (ObjectDisposedException) { } EventArgsManager.Put(ref e); return(true); }
private void Receive_Completed(Socket socket, ServerAsyncEventArgs e) { try { Server <C> .Connection <C> connection; this.connections.TryGetValue(e.RemoteEndPoint, out connection); if (connection != null && connection.Socket == socket && connection.Id == e.ConnectionId) { while (true) { if (e != null) { connection.ReceiveQueue.Put(e); e = null; } e = connection.ReceiveQueue.GetCurrent(); if (e == null) { goto IL_D4; } bool flag = true; if (this.isRunning && e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { flag = !this.OnTcpReceived(connection, ref e); } if (flag) { break; } connection.ReceiveQueue.Next(); if (e == null) { e = EventArgsManager.Get(); } else { e.SetDefaultValue(); } if (this.TcpReceiveAsync(connection, e)) { e = null; } } this.connections.Remove(connection.RemoteEndPoint, connection); this.EndTcpConnection(connection); } IL_D4 :; } finally { if (e != null) { EventArgsManager.Put(ref e); } } }
public void Dispose() { if (this.isPooled) { BufferManager.Free(ref this.segment); this.socketArgs.Dispose(); return; } EventArgsManager.Put(this); }
public void Put(ServerAsyncEventArgs e) { int num = e.SequenceNumber % this.size; Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[num], e); if (this.disposed && Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[num], null) != null) { EventArgsManager.Put(e); } }
public void Dispose() { if (isPooled) { BufferManager.Free(ref segment); socketArgs.Dispose(); } else { EventArgsManager.Put(this); } }
public void Dispose() { this.disposed = true; ServerAsyncEventArgs serverAsyncEventArgs = null; for (int i = 0; i < this.queue.Length; i++) { if (this.queue[i] != null) { serverAsyncEventArgs = Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[i], null); } if (serverAsyncEventArgs != null) { EventArgsManager.Put(ref serverAsyncEventArgs); } } }
private ArraySegment <byte> Detach(ref ServerAsyncEventArgs e, int size) { ServerAsyncEventArgs serverAsyncEventArgs = null; if (e.BytesTransferred > size) { serverAsyncEventArgs = e.CreateDeepCopy(); } ArraySegment <byte> result = e.DetachBuffer(); EventArgsManager.Put(ref e); if (serverAsyncEventArgs != null) { e = serverAsyncEventArgs; } return(result); }
private void Server_Sent(Server <C> server, ServerAsyncEventArgs e) { try { if (this.Sent != null) { this.Sent(this, ref e); } if (e != null) { EventArgsManager.Put(e); } } catch (Exception innerException) { throw new Exception("Error in Sent event handler", innerException); } }
private ArraySegment <byte> Detach(ref ServerAsyncEventArgs e, int size) { ServerAsyncEventArgs copy = null; if (e.BytesTransferred > size) { copy = e.CreateDeepCopy(); } var result = e.DetachBuffer(); EventArgsManager.Put(ref e); if (copy != null) { e = copy; } return(result); }
public void Dispose() { disposed = true; var e = default(ServerAsyncEventArgs); for (int i = 0; i < queue.Length; i++) { if (queue[i] != null) { e = Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[i], null); } if (e != null) { EventArgsManager.Put(ref e); } } }
private void ReceiveFrom_Completed(Socket socket, ServerAsyncEventArgs e) { while (isRunning) { if (e.SocketError == SocketError.Success) { OnReceived(null, ref e); if (e == null) { e = EventArgsManager.Get(); } PrepareBuffer(e); try { if (socket.ReceiveFromAsync(e)) { e = null; break; } } catch (ObjectDisposedException) { } } else { if (isRunning) { Dispose(); OnFailed(new ServerInfoEventArgs(realEndPoint, e.SocketError)); } } } if (e != null) { EventArgsManager.Put(e); } }
public void Put(ServerAsyncEventArgs e) { int index = e.SequenceNumber % size; #if DEBUG if (queue[index] != null) { throw new InvalidOperationException(); } #endif Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[index], e); if (disposed) { if (Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[index], null) != null) { EventArgsManager.Put(e); } } }
private void Receive_Completed(Socket socket, ServerAsyncEventArgs e) { try { Connection <C> connection; connections.TryGetValue(e.RemoteEndPoint, out connection); if (connection != null && connection.Socket == socket && connection.Id == e.ConnectionId) { for (; ;) { if (e != null) { connection.ReceiveQueue.Put(e); e = null; } e = connection.ReceiveQueue.GetCurrent(); if (e == null) { break; } bool close = true; if (isRunning && e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { close = !OnTcpReceived(connection, ref e); } if (close) { connections.Remove(connection.RemoteEndPoint, connection); EndTcpConnection(connection); break; } else { connection.ReceiveQueue.Next(); } if (e == null) { e = EventArgsManager.Get(); } else { e.SetDefaultValue(); } if (TcpReceiveAsync(connection, e)) { e = null; } } } #if DEBUG else { if (e.BytesTransferred > 0) { Console.WriteLine("ERROR: {0}, conn-handle: {1}, socket-handle: {2}, ip: {3}", e.BytesTransferred, (connection == null) ? "Null" : connection.Socket.Handle.ToString(), socket.Handle.ToString(), e.RemoteEndPoint.ToString()); } } #endif } finally { if (e != null) { EventArgsManager.Put(ref e); } } }
unsafe private bool DecryptData(ref ServerAsyncEventArgs e, Connection <C> connection) { var context = connection.SspiContext; var message = context.SecBufferDesc5; if (context.Buffer.IsValid && e != null) { if (context.Buffer.CopyTransferredFrom(e, 0) == false) { return(false); } } for (; ;) { // prepare buffer // message.Buffers[0].BufferType = BufferType.SECBUFFER_DATA; if (context.Buffer.IsValid) { SetSecBuffer(ref message.Buffers[0], context); } else { SetSecBuffer(ref message.Buffers[0], e); } message.Buffers[1].SetBufferEmpty(); message.Buffers[2].SetBufferEmpty(); message.Buffers[3].SetBufferEmpty(); message.Buffers[4].SetBufferEmpty(); // call SSPI // var result = Sspi.SafeDecryptMessage(ref context.Handle, ref message, 0, null); // analize result // int extraIndex = message.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0); int dataIndex = message.GetBufferIndex(BufferType.SECBUFFER_DATA, 0); switch (result) { case SecurityStatus.SEC_E_OK: if (dataIndex >= 0) { if (context.Buffer.IsInvalid) { if (extraIndex >= 0) { if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false) { return(false); } } e.Offset = message.Buffers[dataIndex].Offset; e.BytesTransferred = message.Buffers[dataIndex].Size; e.SetMaxCount(); if (OnReceived(connection, ref e) == false) { return(false); } } else { var buffer = context.Buffer.Detach(); if (extraIndex >= 0) { if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false) { return(false); } } // create eventarg and call onreceived event // var e2 = EventArgsManager.Get(); base.PrepareEventArgs(connection, e2); e2.AttachBuffer(buffer); e2.Offset = message.Buffers[dataIndex].Offset; e2.BytesTransferred = message.Buffers[dataIndex].Size; e2.SetMaxCount(); bool continue1 = OnReceived(connection, ref e2); if (e2 != null) { EventArgsManager.Put(e2); } if (continue1 == false) { return(false); } } if (extraIndex >= 0) { continue; } return(true); } return(false); case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE: if (context.Buffer.IsInvalid) { if (context.Buffer.CopyTransferredFrom(e, 0) == false) { return(false); } } return(true); case SecurityStatus.SEC_I_RENEGOTIATE: // MSDN: Renegotiation is not supported for Schannel kernel mode. The // caller should either ignore this return value or shut down the // connection. // If the value is ignored, either the client or the server might shut // down the connection as a result. return(false); default: return(false); } } }
private unsafe bool Handshake(ServerAsyncEventArgs ie, Connection <C> connection) { int contextAttr = 0; ServerAsyncEventArgs oe = null; var context = connection.SspiContext; var input = context.SecBufferDesc2[0]; var output = context.SecBufferDesc2[1]; try { if (context.Buffer.IsValid && ie != null) { if (context.Buffer.CopyTransferredFrom(ie, 0) == false) { return(false); } } for (; ;) { // prepare input buffer // input.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN; if (context.Buffer.IsValid) { SetSecBuffer(ref input.Buffers[0], context); } else { SetSecBuffer(ref input.Buffers[0], ie); } input.Buffers[1].SetBufferEmpty(); // prepare output buffer // if (oe == null) { oe = EventArgsManager.Get(); } oe.AllocateBuffer(); output.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN; output.Buffers[0].Size = oe.Count; output.Buffers[0].Buffer = oe.Buffer; output.Buffers[0].Offset = oe.Offset; output.Buffers[1].SetBufferEmpty(); // prepare some args and call SSPI // int contextReq = (int)(ContextReq.ASC_REQ_SEQUENCE_DETECT | ContextReq.ASC_REQ_REPLAY_DETECT | ContextReq.ASC_REQ_CONFIDENTIALITY | ContextReq.ASC_REQ_EXTENDED_ERROR | ContextReq.ASC_REQ_STREAM); var newHandle = (context.Handle.IsInvalid) ? new SafeCtxtHandle() : context.Handle; long timeStamp; var result = Sspi.SafeAcceptSecurityContext( ref credential, ref context.Handle, ref input, contextReq, TargetDataRep.SECURITY_NATIVE_DREP, ref newHandle, ref output, out contextAttr, out timeStamp); if (context.Handle.IsInvalid) { context.Handle = newHandle; } // proccess non-critical errors // switch (result) { case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE: if (context.Buffer.IsInvalid) { if (context.Buffer.CopyTransferredFrom(ie, 0) == false) { return(false); } } return(true); case SecurityStatus.SEC_E_BUFFER_TOO_SMALL: if (oe.Count < maxTokenSize) { oe.Count = maxTokenSize; oe.ReAllocateBuffer(false); continue; } return(false); } // send response to client // if (result == SecurityStatus.SEC_I_CONTINUE_NEEDED || result == SecurityStatus.SEC_E_OK || (Sspi.Failed(result) && (contextAttr & (int)ContextAttr.ASC_RET_EXTENDED_ERROR) != 0)) { if (output.Buffers[0].Size > 0) { oe.Count = output.Buffers[0].Size; oe.CopyAddressesFrom(ie); oe.LocalEndPoint = GetLocalEndpoint(ie.RemoteEndPoint.Address); base.SendAsync(connection, oe); oe = null; } } // move extra data to buffer // int extraIndex = input.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0); if (extraIndex < 0) { context.Buffer.Free(); } else { if (context.Buffer.IsInvalid) { if (context.Buffer.CopyTransferredFrom(ie, ie.BytesTransferred - input.Buffers[extraIndex].Size) == false) { return(false); } } else { context.Buffer.MoveToBegin(context.Buffer.BytesTransferred - input.Buffers[extraIndex].Size, input.Buffers[extraIndex].Size); } } // proccess error-codes // switch (result) { case SecurityStatus.SEC_E_OK: if (Sspi.SafeQueryContextAttributes(ref context.Handle, out context.StreamSizes) != SecurityStatus.SEC_E_OK) { return(false); } context.Connected = true; OnNewConnection(connection); return(true); case SecurityStatus.SEC_I_CONTINUE_NEEDED: if (extraIndex >= 0) { continue; } return(true); default: return(false); } } } finally { if (oe != null) { EventArgsManager.Put(ref oe); } } }
private bool DecryptData(ref ServerAsyncEventArgs e, Server <C> .Connection <C> connection) { SspiContext sspiContext = connection.SspiContext; SecBufferDescEx secBufferDesc = sspiContext.SecBufferDesc5; if (sspiContext.Buffer.IsValid && e != null && !sspiContext.Buffer.CopyTransferredFrom(e, 0)) { return(false); } SecurityStatus securityStatus2; while (true) { secBufferDesc.Buffers[0].BufferType = BufferType.SECBUFFER_DATA; if (sspiContext.Buffer.IsValid) { this.SetSecBuffer(ref secBufferDesc.Buffers[0], sspiContext); } else { this.SetSecBuffer(ref secBufferDesc.Buffers[0], e); } secBufferDesc.Buffers[1].SetBufferEmpty(); secBufferDesc.Buffers[2].SetBufferEmpty(); secBufferDesc.Buffers[3].SetBufferEmpty(); secBufferDesc.Buffers[4].SetBufferEmpty(); SecurityStatus securityStatus = Sspi.SafeDecryptMessage(ref sspiContext.Handle, ref secBufferDesc, 0u, null); int bufferIndex = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0); int bufferIndex2 = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_DATA, 0); securityStatus2 = securityStatus; if (securityStatus2 != SecurityStatus.SEC_E_OK) { break; } if (bufferIndex2 < 0) { return(false); } if (sspiContext.Buffer.IsInvalid) { if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex])) { return(false); } e.Offset = secBufferDesc.Buffers[bufferIndex2].Offset; e.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size; e.SetMaxCount(); if (!this.OnReceived(connection, ref e)) { return(false); } } else { ArraySegment <byte> buffer = sspiContext.Buffer.Detach(); if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex])) { return(false); } ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get(); base.PrepareEventArgs(connection, serverAsyncEventArgs); serverAsyncEventArgs.AttachBuffer(buffer); serverAsyncEventArgs.Offset = secBufferDesc.Buffers[bufferIndex2].Offset; serverAsyncEventArgs.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size; serverAsyncEventArgs.SetMaxCount(); bool flag = this.OnReceived(connection, ref serverAsyncEventArgs); if (serverAsyncEventArgs != null) { EventArgsManager.Put(serverAsyncEventArgs); } if (!flag) { return(false); } } if (bufferIndex < 0) { return(true); } } return(securityStatus2 != SecurityStatus.SEC_I_RENEGOTIATE && securityStatus2 == (SecurityStatus)2148074264u && (!sspiContext.Buffer.IsInvalid || sspiContext.Buffer.CopyTransferredFrom(e, 0))); }
private bool Handshake(ServerAsyncEventArgs ie, Server <C> .Connection <C> connection) { int num = 0; ServerAsyncEventArgs serverAsyncEventArgs = null; SspiContext sspiContext = connection.SspiContext; SecBufferDescEx secBufferDescEx = sspiContext.SecBufferDesc2[0]; SecBufferDescEx secBufferDescEx2 = sspiContext.SecBufferDesc2[1]; bool result; try { if (sspiContext.Buffer.IsValid && ie != null && !sspiContext.Buffer.CopyTransferredFrom(ie, 0)) { result = false; } else { while (true) { secBufferDescEx.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN; if (sspiContext.Buffer.IsValid) { this.SetSecBuffer(ref secBufferDescEx.Buffers[0], sspiContext); } else { this.SetSecBuffer(ref secBufferDescEx.Buffers[0], ie); } secBufferDescEx.Buffers[1].SetBufferEmpty(); if (serverAsyncEventArgs == null) { serverAsyncEventArgs = EventArgsManager.Get(); } serverAsyncEventArgs.AllocateBuffer(); secBufferDescEx2.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN; secBufferDescEx2.Buffers[0].Size = serverAsyncEventArgs.Count; secBufferDescEx2.Buffers[0].Buffer = serverAsyncEventArgs.Buffer; secBufferDescEx2.Buffers[0].Offset = serverAsyncEventArgs.Offset; secBufferDescEx2.Buffers[1].SetBufferEmpty(); int contextReq = 98332; SafeCtxtHandle handle = sspiContext.Handle.IsInvalid ? new SafeCtxtHandle() : sspiContext.Handle; long num2; SecurityStatus securityStatus = Sspi.SafeAcceptSecurityContext(ref this.credential, ref sspiContext.Handle, ref secBufferDescEx, contextReq, TargetDataRep.SECURITY_NATIVE_DREP, ref handle, ref secBufferDescEx2, out num, out num2); if (sspiContext.Handle.IsInvalid) { sspiContext.Handle = handle; } SecurityStatus securityStatus2 = securityStatus; if (securityStatus2 == (SecurityStatus)2148074264u) { break; } if (securityStatus2 != (SecurityStatus)2148074273u) { if ((securityStatus == SecurityStatus.SEC_I_CONTINUE_NEEDED || securityStatus == SecurityStatus.SEC_E_OK || (Sspi.Failed(securityStatus) && (num & 32768) != 0)) && secBufferDescEx2.Buffers[0].Size > 0) { serverAsyncEventArgs.Count = secBufferDescEx2.Buffers[0].Size; serverAsyncEventArgs.CopyAddressesFrom(ie); serverAsyncEventArgs.LocalEndPoint = base.GetLocalEndpoint(ie.RemoteEndPoint.Address); base.SendAsync(connection, serverAsyncEventArgs); serverAsyncEventArgs = null; } int bufferIndex = secBufferDescEx.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0); if (bufferIndex < 0) { sspiContext.Buffer.Free(); } else if (sspiContext.Buffer.IsInvalid) { if (!sspiContext.Buffer.CopyTransferredFrom(ie, ie.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size)) { goto Block_21; } } else { sspiContext.Buffer.MoveToBegin(sspiContext.Buffer.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size, secBufferDescEx.Buffers[bufferIndex].Size); } SecurityStatus securityStatus3 = securityStatus; if (securityStatus3 == SecurityStatus.SEC_E_OK) { goto IL_2FF; } if (securityStatus3 != SecurityStatus.SEC_I_CONTINUE_NEEDED) { goto Block_23; } if (bufferIndex < 0) { goto Block_25; } } else { if (serverAsyncEventArgs.Count >= this.maxTokenSize) { goto IL_1DC; } serverAsyncEventArgs.Count = this.maxTokenSize; serverAsyncEventArgs.ReAllocateBuffer(false); } } if (sspiContext.Buffer.IsInvalid && !sspiContext.Buffer.CopyTransferredFrom(ie, 0)) { result = false; return(result); } result = true; return(result); IL_1DC: result = false; return(result); Block_21: result = false; return(result); Block_23: result = false; return(result); IL_2FF: if (Sspi.SafeQueryContextAttributes(ref sspiContext.Handle, out sspiContext.StreamSizes) != SecurityStatus.SEC_E_OK) { result = false; return(result); } sspiContext.Connected = true; this.OnNewConnection(connection); result = true; return(result); Block_25: result = true; } } finally { if (serverAsyncEventArgs != null) { EventArgsManager.Put(ref serverAsyncEventArgs); } } return(result); }