private async Task StartConnect(int port) { SaeaAwaitable tcpSaea = null; try { tcpSaea = _argsPool.Rent(); var realSaea = tcpSaea.Saea; realSaea.RemoteEndPoint = SocketUtil.GetEndPoint("127.0.0.1", port); tcpSaea.PrepareSAEABuffer(_firstPacket, _firstPacketLength); var ret = await _remote.ConnectAsync(tcpSaea); if (ret != SocketError.Success) { Close(); return; } Task.Factory.StartNew(StartPipe, TaskCreationOptions.PreferFairness).Forget(); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(tcpSaea); tcpSaea = null; } }
private async Task StartRecvFrom() { SaeaAwaitable udpSaea = null; try { while (IsListening) { udpSaea = _argsPool.Rent(); udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); var err = await _udpSocket.ReceiveFromAsync(udpSaea); var saea = udpSaea.Saea; var bytesRecved = saea.BytesTransferred; if (err == SocketError.Success && bytesRecved > 0) { ServiceUserToken token = new ServiceUserToken { socket = _udpSocket, firstPacket = new byte[bytesRecved], firstPacketLength = bytesRecved, remoteEndPoint = saea.RemoteEndPoint }; Buffer.BlockCopy(saea.Buffer, 0, token.firstPacket, 0, bytesRecved); Task.Factory.StartNew(() => HandleUDPServices(token)).Forget(); } else { Logging.Error($"RecvFrom: {err},{bytesRecved}"); } _argsPool.Return(udpSaea); udpSaea = null; } } catch (Exception e) { Logging.LogUsefulException(e); } finally { _argsPool.Return(udpSaea); udpSaea = null; } }
private async Task StartRecvFrom() { SaeaAwaitable udpSaea = null; try { while (IsListening) { udpSaea = _argsPool.Rent(); udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); var err = await _udpSocket.ReceiveFromAsync(udpSaea); ServiceUserToken token = new ServiceUserToken(); if (err == SocketError.Success && udpSaea.Saea.BytesTransferred > 0) { var e = udpSaea.Saea; token.socket = _udpSocket; token.firstPacket = new byte[e.BytesTransferred]; token.firstPacketLength = e.BytesTransferred; token.remoteEndPoint = e.RemoteEndPoint; Buffer.BlockCopy(e.Buffer, e.Offset, token.firstPacket, 0, e.BytesTransferred); } _argsPool.Return(udpSaea); udpSaea = null; foreach (IService service in _services) { if (service.Handle(token)) { return; } } } } catch (Exception e) { Logging.LogUsefulException(e); } finally { _argsPool.Return(udpSaea); udpSaea = null; } }
private async Task Accept() { SaeaAwaitable saea = null; try { while (IsListening) { saea = _acceptArgsPool.Rent(); var socketError = await _tcpListenerSocket.AcceptAsync(saea); if (socketError == SocketError.Success) { Logging.Debug("accepted a connection"); var acceptedSocket = saea.Saea.AcceptSocket; Task.Factory.StartNew(async() => { await RecvFirstPacket(acceptedSocket); }, TaskCreationOptions.PreferFairness).Forget(); } else { Logging.Error($"Accept socket err: {socketError}"); } _acceptArgsPool.Return(saea); saea = null; } } catch (Exception ex) { Logging.LogUsefulException(ex); } finally { _acceptArgsPool.Return(saea); saea = null; } }
public async Task Start(byte[] data, int length) { Interlocked.Exchange(ref _state, _running); SaeaAwaitable upSaea = null; SaeaAwaitable downSaea = null; try { Logging.Debug($"-----UDP relay got {length}-----"); IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); byte[] dataIn = new byte[length - 3]; Array.Copy(data, 3, dataIn, 0, length - 3); upSaea = _argsPool.Rent(); int outlen; encryptor.EncryptUDP(dataIn, dataIn.Length, upSaea.Saea.Buffer, out outlen); upSaea.Saea.SetBuffer(0, outlen); upSaea.Saea.RemoteEndPoint = _serverEndPoint; var ret = await _serverSocket.SendToAsync(upSaea); if (ret != SocketError.Success) { Logging.Error($"[udp] remote sendto {ret},{upSaea.Saea.BytesTransferred}"); Close(); return; } Logging.Debug($"[udp] remote sendto {_localEndPoint} -> {_serverEndPoint} {upSaea.Saea.BytesTransferred}"); _argsPool.Return(upSaea); upSaea = null; while (IsRunning) { downSaea = _argsPool.Rent(); downSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ret = await _serverSocket.ReceiveFromAsync(downSaea); var bytesReceived = downSaea.Saea.BytesTransferred; if (ret != SocketError.Success) { Logging.Error($"[udp] remote recvfrom {ret},{bytesReceived}"); Close(); return; } Logging.Debug($"[udp] remote recvfrom {downSaea.Saea.RemoteEndPoint} -> {_localSocket.LocalEndPoint} {bytesReceived}"); byte[] dataOut = new byte[bytesReceived]; encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); encryptor.DecryptUDP(downSaea.Saea.Buffer, bytesReceived, dataOut, out outlen); downSaea.ClearAndResetSaeaProperties(); byte[] buf = downSaea.Saea.Buffer; buf[0] = buf[1] = buf[2] = 0; Array.Copy(dataOut, 0, buf, 3, outlen); downSaea.Saea.RemoteEndPoint = _localEndPoint; downSaea.Saea.SetBuffer(0, outlen + 3); ret = await _localSocket.SendToAsync(downSaea); if (ret != SocketError.Success) { Logging.Error($"[udp] local sendto {ret},{downSaea.Saea.BytesTransferred}"); Close(); return; } Logging.Debug($"[udp] local sendto {_localSocket.LocalEndPoint} -> {_localEndPoint} {downSaea.Saea.BytesTransferred}"); _argsPool.Return(downSaea); downSaea = null; } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(upSaea); upSaea = null; _argsPool.Return(downSaea); downSaea = null; } }
private async Task HandshakeSendResponse() { SaeaAwaitable tcpSaea = null; try { if (_firstPacketLength <= 1) { Logging.Debug("Invalid first packet length"); Close(); return; } byte[] response = TCPRelay.Sock5HandshakeResponseSuccess; if (_firstPacket[0] != 5) { // reject socks 4 response = TCPRelay.Sock5HandshakeResponseReject; Logging.Error("socks 5 protocol error"); } tcpSaea = _argsPool.Rent(); tcpSaea.PrepareSAEABuffer(response, response.Length); var token = await _localSocket.FullSendTaskAsync(tcpSaea, response.Length); var err = token.SocketError; var bytesSent = token.BytesTotalTransferred; Logging.Debug($"HandshakeSendResponse: {err},{bytesSent}"); if (err != SocketError.Success) { Close(); return; } _argsPool.Return(tcpSaea); tcpSaea = null; Debug.Assert(bytesSent == response.Length); Task.Factory.StartNew(async() => { await Sock5RequestRecv(); }).Forget(); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(tcpSaea); tcpSaea = null; } }
public async Task Start(byte[] data, int length) { Interlocked.Exchange(ref _state, _running); SaeaAwaitable udpSaea = null; try { while (IsRunning) { IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); byte[] dataIn = new byte[length - 3]; Array.Copy(data, 3, dataIn, 0, length - 3); udpSaea = _argsPool.Rent(); int outlen; encryptor.EncryptUDP(dataIn, length - 3, udpSaea.Saea.Buffer, out outlen); udpSaea.Saea.SetBuffer(0, outlen); udpSaea.Saea.RemoteEndPoint = _remoteEndPoint; Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); var ret = await _remote.SendToAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } udpSaea = _argsPool.Rent(); udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ret = await _remote.ReceiveFromAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } var bytesReceived = udpSaea.Saea.BytesTransferred; Logging.Debug($"++++++Receive Server Port, size:" + bytesReceived); byte[] dataOut = new byte[bytesReceived]; encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); encryptor.DecryptUDP(udpSaea.Saea.Buffer, bytesReceived, dataOut, out outlen); _argsPool.Return(udpSaea); udpSaea = null; udpSaea = _argsPool.Rent(); byte[] buf = udpSaea.Saea.Buffer; buf[0] = buf[1] = buf[2] = 0; Array.Copy(dataOut, 0, buf, 3, outlen); udpSaea.Saea.RemoteEndPoint = _localEndPoint; udpSaea.Saea.SetBuffer(0, outlen + 3); Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); ret = await _local.SendToAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } _argsPool.Return(udpSaea); udpSaea = null; } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(udpSaea); udpSaea = null; } }