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;
                }
            }
Esempio n. 2
0
        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;
            }
        }
Esempio n. 3
0
        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;
            }
        }
Esempio n. 4
0
        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;
            }
        }