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 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; } }
private async Task Sock5ConnectResponseSend() { SaeaAwaitable tcpSaea = null; try { tcpSaea = _argsPool.Rent(); tcpSaea.PrepareSAEABuffer(TCPRelay.Sock5ConnectRequestReplySuccess, TCPRelay.Sock5ConnectRequestReplySuccess.Length); var token = await _localSocket.FullSendTaskAsync(tcpSaea, TCPRelay.Sock5ConnectRequestReplySuccess.Length); var err = token.SocketError; var bytesSent = token.BytesTotalTransferred; Logging.Debug($"Sock5ConnectResponseSend: {err},{bytesSent}"); if (err != SocketError.Success) { Close(); return; } _argsPool.Return(tcpSaea); tcpSaea = null; Debug.Assert(bytesSent == TCPRelay.Sock5ConnectRequestReplySuccess.Length); Task.Factory.StartNew(async() => { await StartConnect(); }).Forget(); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(tcpSaea); tcpSaea = null; } }
private async Task HandleUDPAssociate() { IPEndPoint endPoint = (IPEndPoint)_localSocket.LocalEndPoint; IPAddress endPointAddress = endPoint.Address; if (endPointAddress.IsIPv4MappedToIPv6) { endPointAddress = endPointAddress.MapToIPv4(); } byte[] address = endPointAddress.GetAddressBytes(); int port = endPoint.Port; byte[] response = new byte[4 + address.Length + ADDR_PORT_LEN]; response[0] = 5; switch (endPointAddress.AddressFamily) { case AddressFamily.InterNetwork: response[3] = ATYP_IPv4; break; case AddressFamily.InterNetworkV6: response[3] = ATYP_IPv6; break; } Array.Copy(address, 0, response, 4, address.Length); response[response.Length - 1] = (byte)(port & 0xFF); response[response.Length - 2] = (byte)((port >> 8) & 0xFF); SaeaAwaitable tcpSaea = null; SaeaAwaitable circularRecvSaea = null; try { tcpSaea = _argsPool.Rent(); tcpSaea.PrepareSAEABuffer(response, response.Length); var token = await _localSocket.FullSendTaskAsync(tcpSaea, response.Length); var err = token.SocketError; var sentSize = token.BytesTotalTransferred; Logging.Debug($"Udp assoc local send: {err},{sentSize}"); if (err != SocketError.Success) { Close(); return; } Debug.Assert(sentSize == response.Length); _argsPool.Return(tcpSaea); tcpSaea = null; circularRecvSaea = _argsPool.Rent(); while (IsRunning) { // UDP Assoc: Read all from socket and wait until client closes the connection token = await _localSocket.FullReceiveTaskAsync(circularRecvSaea, TCPRelay.RecvSize); Logging.Debug($"udp assoc local recv: {err}"); var ret = token.SocketError; var bytesRecved = token.BytesTotalTransferred; if (ret != SocketError.Success) { Logging.Error($"udp assoc: {ret},{bytesRecved}"); Close(); return; } if (bytesRecved <= 0) { Close(); return; } circularRecvSaea.ClearAndResetSaeaProperties(); } _argsPool.Return(circularRecvSaea); circularRecvSaea = null; } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(tcpSaea); tcpSaea = null; _argsPool.Return(circularRecvSaea); circularRecvSaea = null; } }