private void PipeRemoteReceiveCallback(IAsyncResult ar) { if (_closed) { return; } try { var session = (AsyncSession)ar.AsyncState; int bytesRead = session.Remote.EndReceive(ar); _totalRead += bytesRead; _tcprelay.UpdateInboundCounter(_server, bytesRead); if (bytesRead > 0) { lastActivity = DateTime.Now; int bytesToSend = -1; lock (_decryptionLock) { try { _encryptor.Decrypt(_remoteRecvBuffer, bytesRead, _remoteSendBuffer, out bytesToSend); } catch (CryptoErrorException) { Logging.Error("decryption error"); Close(); return; } } if (bytesToSend == 0) { // need more to decrypt Logging.Debug("Need more to decrypt"); session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, PipeRemoteReceiveCallback, session); return; } Logging.Debug($"start sending {bytesToSend}"); _connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, PipeConnectionSendCallback, new object[] { session, bytesToSend }); IStrategy strategy = _controller.GetCurrentStrategy(); strategy?.UpdateLastRead(_server); } else { _connection.Shutdown(SocketShutdown.Send); _connectionShutdown = true; CheckClose(); } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
private void PipeRemoteReceiveCallback(IAsyncResult ar) { if (_closed) { return; } try { int bytesRead = _remote.EndReceive(ar); _totalRead += bytesRead; _tcprelay.UpdateInboundCounter(_server, bytesRead); if (bytesRead > 0) { lastActivity = DateTime.Now; int bytesToSend = -1; lock (_decryptionLock) { try { _encryptor.Decrypt(_remoteRecvBuffer, bytesRead, _remoteSendBuffer, out bytesToSend); } catch (CryptoErrorException e) { Logging.LogUsefulException(e); Close(); return; } } if (bytesToSend == 0) { // need more to decrypt Logging.Debug("Need more to decrypt"); _remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, PipeRemoteReceiveCallback, null); return; } Logging.Debug($"start sending {bytesToSend}"); _connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, PipeConnectionSendCallback, bytesToSend); } else { _connection.Shutdown(SocketShutdown.Send); _connectionShutdown = true; CheckClose(); } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
// server recv -> local send private async Task Downstream() { SaeaAwaitable serverRecvSaea = null; SaeaAwaitable localSendSaea = null; try { while (IsRunning) { serverRecvSaea = _argsPool.Rent(); var token = await _serverSocket.FullReceiveTaskAsync(serverRecvSaea, TCPRelay.RecvSize); var err = token.SocketError; var bytesRecved = token.BytesTotalTransferred; Logging.Debug($"Downstream server recv: {err},{bytesRecved}"); if (err == SocketError.Success && bytesRecved <= 0) { _localSocket.Shutdown(SocketShutdown.Send); _localShutdown = true; CheckClose(); return; } if (err != SocketError.Success) { Logging.Debug($"Downstream server recv socket err: {err}"); Close(); return; } Debug.Assert(bytesRecved <= TCPRelay.RecvSize); _tcprelay.UpdateInboundCounter(_server, bytesRecved); lastActivity = DateTime.Now; localSendSaea = _argsPool.Rent(); int decBufLen = -1; lock (_decryptionLock) { _encryptor.Decrypt(serverRecvSaea.Saea.Buffer, bytesRecved, localSendSaea.Saea.Buffer, out decBufLen); } _argsPool.Return(serverRecvSaea); serverRecvSaea = null; token = await _localSocket.FullSendTaskAsync(localSendSaea, decBufLen); err = token.SocketError; var bytesSent = token.BytesTotalTransferred; Logging.Debug($"Downstream local send socket err: {err},{bytesSent}"); if (err != SocketError.Success) { Close(); return; } _argsPool.Return(localSendSaea); localSendSaea = null; Debug.Assert(bytesSent == decBufLen); } } catch (AggregateException agex) { foreach (var ex in agex.InnerExceptions) { Logging.LogUsefulException(ex); } Close(); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(serverRecvSaea); serverRecvSaea = null; _argsPool.Return(localSendSaea); localSendSaea = null; } }