コード例 #1
0
        /// <summary>
        /// Opens the output.
        /// </summary>
        /// <param name="Client">SOCKS5 client with established connection.</param>
        public async Task Opened(Socks5Client Client)
        {
            Client.OnWriteQueueEmpty += this.WriteQueueEmpty;
            this.client = Client;

            if (!(this.tempFile is null))
            {
                if (!await this.syncObject.TryBeginWrite(10000))
                {
                    throw new TimeoutException();
                }

                try
                {
                    if (!this.isWriting && (this.tempFile.Length - this.pos >= this.blockSize ||
                                            (this.done && this.tempFile.Length > this.pos)))
                    {
                        await this.WriteBlockLocked();
                    }
                }
                finally
                {
                    await this.syncObject.EndWrite();
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// Event arguments for data reception events.
 /// </summary>
 /// <param name="Buffer">Binary Data Buffer</param>
 /// <param name="Offset">Start index of first byte received.</param>
 /// <param name="Count">Number of bytes received.</param>
 /// <param name="Stream">SOCKS5 client stream.</param>
 /// <param name="State">State</param>
 internal DataReceivedEventArgs(byte[] Buffer, int Offset, int Count, Socks5Client Stream, object State)
 {
     this.buffer = Buffer;
     this.offset = Offset;
     this.count  = Count;
     this.stream = Stream;
     this.state  = State;
 }
コード例 #3
0
        /// <summary>
        /// Opens the output.
        /// </summary>
        /// <param name="Client">SOCKS5 client with established connection.</param>
        public void Opened(Socks5Client Client)
        {
            Client.OnWriteQueueEmpty += this.WriteQueueEmpty;
            this.client = Client;

            if (!this.isWriting && this.tempFile.Length - this.pos >= this.blockSize)
            {
                this.WriteBlockLocked();
            }
        }
コード例 #4
0
 /// <summary>
 /// Class managing the transmission of a SOCKS5 bytestream.
 /// </summary>
 /// <param name="Client">XMPP client.</param>
 /// <param name="To">To</param>
 /// <param name="BlockSize">Block size</param>
 /// <param name="E2E">End-to-end encryption, if used.</param>
 public OutgoingStream(XmppClient Client, string To, int BlockSize, IEndToEndEncryption E2E)
 {
     this.xmppClient = Client;
     this.client     = null;
     this.to         = To;
     this.blockSize  = BlockSize;
     this.e2e        = E2E;
     this.isWriting  = false;
     this.done       = false;
     this.tempFile   = new TemporaryFile();
 }
コード例 #5
0
        private async Task ClientStateChanged(object Sender, EventArgs e3)
        {
            Socks5Client     Client = (Socks5Client)Sender;
            Socks5QueryState State  = (Socks5QueryState)Client.Tag;

            switch (Client.State)
            {
            case Socks5State.Authenticated:
                Client.CONNECT(State.streamId, State.eventargs.From, this.client.FullJID);
                break;

            case Socks5State.Connected:
                StringBuilder Xml = new StringBuilder();

                Xml.Append("<query xmlns=\"");
                Xml.Append(Namespace);
                Xml.Append("\" sid=\"");
                Xml.Append(State.streamId);
                Xml.Append("\"><streamhost-used jid=\"");
                Xml.Append(Client.Host);
                Xml.Append("\"/></query>");

                State.eventargs.IqResult(Xml.ToString());
                break;

            case Socks5State.Error:
            case Socks5State.Offline:
                if (Client.State == Socks5State.Error)
                {
                    State.eventargs.IqError(new BadRequestException("Unable to establish a SOCKS5 connection.", State.eventargs.IQ));
                }

                Client.Dispose();

                lock (this.streams)
                {
                    this.streams.Remove(State.streamId);
                }

                if (State.eventargs2.CloseCallback != null)
                {
                    try
                    {
                        await State.eventargs2.CloseCallback(this, new StreamEventArgs(false, Client, State.eventargs2.State));
                    }
                    catch (Exception ex)
                    {
                        Log.Critical(ex);
                    }
                }
                break;
            }
        }
コード例 #6
0
 /// <summary>
 /// Class managing the transmission of a SOCKS5 bytestream.
 /// </summary>
 /// <param name="StreamId">Stream ID.</param>
 /// <param name="From">From</param>
 /// <param name="To">To</param>
 /// <param name="BlockSize">Block size</param>
 /// <param name="E2E">End-to-end encryption, if used.</param>
 public OutgoingStream(string StreamId, string From, string To, int BlockSize, IEndToEndEncryption E2E)
 {
     this.client    = null;
     this.sid       = StreamId;
     this.from      = From;
     this.to        = To;
     this.blockSize = BlockSize;
     this.e2e       = E2E;
     this.isWriting = false;
     this.done      = false;
     this.tempFile  = new TemporaryFile();
 }
コード例 #7
0
 /// <summary>
 /// Class managing the transmission of a SOCKS5 bytestream.
 /// </summary>
 /// <param name="StreamId">Stream ID.</param>
 /// <param name="From">From</param>
 /// <param name="To">To</param>
 /// <param name="BlockSize">Block size</param>
 /// <param name="E2E">End-to-end encryption, if used.</param>
 public OutgoingStream(string StreamId, string From, string To, int BlockSize, IEndToEndEncryption E2E)
 {
     this.client     = null;
     this.sid        = StreamId;
     this.from       = From;
     this.to         = To;
     this.blockSize  = BlockSize;
     this.e2e        = E2E;
     this.isWriting  = false;
     this.done       = false;
     this.tempStream = new TemporaryStream();
     this.syncObject = new MultiReadSingleWriteObject();
 }
コード例 #8
0
        /// <summary>
        /// Opens the output.
        /// </summary>
        /// <param name="Client">SOCKS5 client with established connection.</param>
        public void Opened(Socks5Client Client)
        {
            Client.OnWriteQueueEmpty += this.WriteQueueEmpty;
            this.client = Client;

            if (!(this.tempFile is null))
            {
                lock (this.tempFile)
                {
                    if (!this.isWriting && (this.tempFile.Length - this.pos >= this.blockSize ||
                                            (this.done && this.tempFile.Length > this.pos)))
                    {
                        this.WriteBlockLocked();
                    }
                }
            }
        }
コード例 #9
0
        private void Callback(StreamEventHandler Callback, object State, bool Ok, Socks5Client Stream, string StreamId)
        {
            if (!Ok && !string.IsNullOrEmpty(StreamId))
            {
                lock (this.streams)
                {
                    this.streams.Remove(StreamId);
                }
            }

            if (Callback != null)
            {
                try
                {
                    Callback(this, new StreamEventArgs(Ok, Stream, State));
                }
                catch (Exception ex)
                {
                    Log.Critical(ex);
                }
            }
        }
コード例 #10
0
        private async Task QueryHandler(object Sender, IqEventArgs e)
        {
            string     StreamId = XML.Attribute(e.Query, "sid");
            XmlElement E;

            if (string.IsNullOrEmpty(StreamId) || StreamId != Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(StreamId)))
            {
                throw new NotAcceptableException("Invalid Stream ID.", e.IQ);
            }

            string Host = null;
            string JID  = null;
            int    Port = 0;

            foreach (XmlNode N in e.Query.ChildNodes)
            {
                E = N as XmlElement;
                if (E is null)
                {
                    continue;
                }

                if (E.LocalName == "streamhost" && E.NamespaceURI == Namespace)
                {
                    Host = XML.Attribute(E, "host");
                    JID  = XML.Attribute(E, "jid");
                    Port = XML.Attribute(E, "port", 0);

                    break;
                }
            }

            if (string.IsNullOrEmpty(JID) || string.IsNullOrEmpty(Host) || Port <= 0 || Port >= 0x10000)
            {
                throw new BadRequestException("Invalid parameters.", e.IQ);
            }

            ValidateStreamEventHandler h  = this.OnOpen;
            ValidateStreamEventArgs    e2 = new ValidateStreamEventArgs(this.client, e, StreamId);

            if (h != null)
            {
                try
                {
                    await h(this, e2);
                }
                catch (Exception ex)
                {
                    Log.Critical(ex);
                }
            }

            if (e2.DataCallback is null || e2.CloseCallback is null)
            {
                throw new NotAcceptableException("Stream not expected.", e.IQ);
            }

            Socks5Client Client;

            lock (this.streams)
            {
                if (this.streams.ContainsKey(StreamId))
                {
                    throw new ConflictException("Stream already exists.", e.IQ);
                }

                Client = new Socks5Client(Host, Port, JID)
                {
                    CallbackState = e2.State
                };

                this.streams[StreamId] = Client;
            }

            Client.Tag = new Socks5QueryState()
            {
                streamId   = StreamId,
                eventargs  = e,
                eventargs2 = e2
            };

            Client.OnDataReceived += e2.DataCallback;
            Client.OnStateChange  += this.ClientStateChanged;
        }
コード例 #11
0
 /// <summary>
 /// Event arguments for data reception events.
 /// </summary>
 /// <param name="Data">Data received.</param>
 /// <param name="Stream">SOCKS5 client stream.</param>
 /// <param name="State">State</param>
 internal DataReceivedEventArgs(byte[] Data, Socks5Client Stream, object State)
 {
     this.data   = Data;
     this.stream = Stream;
     this.state  = State;
 }
コード例 #12
0
 /// <summary>
 /// Event arguments for stream callbacks.
 /// </summary>
 /// <param name="Ok">If request was successful.</param>
 /// <param name="Stream">Stream object.</param>
 /// <param name="State">State object.</param>
 public StreamEventArgs(bool Ok, Socks5Client Stream, object State)
 {
     this.ok     = Ok;
     this.stream = Stream;
     this.state  = State;
 }