예제 #1
0
        private void ReceiveComplete(object sender, IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            if (e.Task.Exception == null)
            {
                Monitor.AddInput(e.Task.Transferred);
                OnPacketReceived(
                    e.Buffer.Buffer[e.Buffer.Offset], //id
                    e.Buffer.Buffer, e.Buffer.Offset + 1,
                    e.Task.Transferred - 1,
                    e.Task.RemoteEndPoint);

                e.Task.RemoteEndPoint = receiveEp;
                if (Socket != null)
                {
                    Socket.QueueReceive(e.Task);
                }
            }
            else
            {
                OnException(e.Task.Exception, e.Task.RemoteEndPoint);
                if (Socket != null)
                {
                    Socket.QueueReceive(e.Task);
                }
            }
        }
예제 #2
0
        protected virtual void SendComplete(object sender, IOTaskCompleteEventArgs <SocketSendTask> e)
        {
            e.Task.Completed -= SendComplete;

            var msg = (IPacket)e.Task.UserToken;

            if (msg.Id == (byte)AresId.MSG_CHAT_SERVER_HTML)
            {
            }

            if (e.Task.Exception == null)
            {
                Monitor.AddOutput(e.Task.Transferred);
                try {
                    PacketSent?.Invoke(this, new PacketEventArgs(msg, MessageType, e.Task.Transferred));

                    if (IsConnected)
                    {
                        SendQueue();
                    }
                }
                catch (Exception ex) {
                    OnException(ex);
                }
            }
            else
            {
                OnException(e.Task.Exception);
            }
        }
예제 #3
0
        private void SendComplete(object sender, IOTaskCompleteEventArgs <SocketSendTask> e)
        {
            e.Task.Completed -= SendComplete;

            if (e.Task.Exception == null)
            {
                Monitor.AddOutput(e.Task.Transferred);
                try {
                    var msg = (IPacket)e.Task.UserToken;

                    var complete = PacketSent;
                    if (complete != null)
                    {
                        complete(this, new PacketEventArgs(msg, e.Task.Transferred, e.Task.RemoteEndPoint));
                    }
                }
                catch (Exception ex) {
                    OnException(ex, e.Task.RemoteEndPoint);
                }
            }
            else
            {
                OnException(e.Task.Exception, e.Task.RemoteEndPoint);
            }
        }
예제 #4
0
        protected virtual void HandleWebSocketLength(IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            var state = (WebSocketReceiveState)e.Task.UserToken;

            byte[] tmp = new byte[e.Task.Transferred];
            Array.Copy(e.Buffer.Buffer, e.Buffer.Offset, tmp, 0, tmp.Length);

            tmp = tmp.EnsureEndian();

            switch (e.Task.Transferred)
            {
            case 2: e.Task.Count = BitConverter.ToUInt16(tmp, 0); break;

            case 8: e.Task.Count = (int)BitConverter.ToUInt64(tmp, 0); break;
            }

            State = ReceiveStatus.Payload;

            if (state.IsMasking)
            {
                e.Task.Count += 4;
            }
            if (IsConnected)
            {
                Socket.QueueReceive(e.Task);
            }
        }
예제 #5
0
        private void SendComplete(object sender, IOTaskCompleteEventArgs <SocketSendTask> e)
        {
            sending           = false;
            e.Task.Completed -= SendComplete;

            if (e.Task.Exception == null)
            {
                Monitor.AddOutput(e.Task.Transferred);
                try {
                    var msg = (IPacket)e.Task.UserToken;

                    var complete = PacketSent;
                    if (complete != null)
                    {
                        complete(this, new PacketEventArgs(msg, e.Task.Transferred));
                    }

                    if (Connected)
                    {
                        SendQueue();
                    }
                }
                catch (Exception ex) {
                    OnException(ex);
                }
            }
            else
            {
                OnException(e.Task.Exception);
            }
        }
예제 #6
0
 protected virtual void OnDisconnected(object sender, IOTaskCompleteEventArgs <SocketDisconnectTask> e)
 {
     disconnecting     = false;
     disconnected      = true;
     e.Task.Completed -= OnDisconnected;
     Disconnected?.Invoke(this, new DisconnectEventArgs(e.Task.UserToken));
 }
예제 #7
0
        private void OnDisconnected(object sender, IOTaskCompleteEventArgs <SocketDisconnectTask> e)
        {
            e.Task.Completed -= OnDisconnected;

            var x = Disconnected;

            if (x != null)
            {
                x(this, new DisconnectEventArgs(e.Task.UserToken));
            }
        }
예제 #8
0
        protected virtual void AcceptComplete(object sender, IOTaskCompleteEventArgs <SocketAcceptTask> e)
        {
            if (e.Task.Exception == null)
            {
                Accepted?.Invoke(this, new AcceptEventArgs(new AresTcpSocket(Formatter, e.Task.AcceptSocket)));
            }

            if (Socket != null)
            {
                Socket.QueueAccept(e.Task);
            }
        }
예제 #9
0
        protected virtual void HandleRequestBody(IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            var token = (HttpRequestState)e.Task.UserToken;

            token.Total += e.Task.Transferred;
            token.Buffer.AddRange(e.Buffer.Buffer.Skip(e.Buffer.Offset).Take(e.Task.Transferred));

            token.Content = Encoding.UTF8.GetString(token.Buffer.ToArray());
            OnHttpRequestReceived(token);

            e.Task.UserToken = null;
            ReceiveAsyncInternal(e.Task);
        }
예제 #10
0
            private void TestComplete(object sender, IOTaskCompleteEventArgs <SocketConnectTask> e)
            {
                e.Task.Completed -= TestComplete;

                if (e.Task.Exception == null)
                {
                    Succeeded = e.Task.Socket.Connected;
                }

                Complete?.Invoke(this, EventArgs.Empty);

                socket.Destroy();
            }
예제 #11
0
        protected virtual void ReceiveCompleted2(object sender, IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            if (e.Task.Exception == null)
            {
                Monitor.AddInput(e.Task.Transferred);

                try {
                    bool finished = true;

                    readStream.Write(e.Buffer.Buffer, e.Buffer.Offset, e.Task.Transferred);
                    readStream.Position = 0;

                    long start = 0;
                    using var reader = new PacketReader(readStream, true);

                    while (finished && reader.Remaining > 0)
                    {
                        start    = reader.Position;
                        finished = ReadPacketHeader(reader);
                    }

                    if (finished)
                    {
                        readStream.SetLength(0);
                    }
                    else
                    {
                        RepositionStream(reader, start);
                    }
                }
                catch (Exception ex) { OnException(ex); }
            }
            else
            {
                OnException(e.Task.Exception);
            }

            if (IsConnected)
            {
                ReceiveAsyncInternal(e.Task);
            }
            else
            {
                e.Task.Completed -= recvHandler;
            }
        }
예제 #12
0
        private void AcceptComplete(object sender, IOTaskCompleteEventArgs <SocketAcceptTask> e)
        {
            SocketAcceptTask task = (SocketAcceptTask)e.Task;

            if (task.Exception == null)
            {
                var x = Accepted;
                if (x != null)
                {
                    x(this, new AcceptEventArgs(new AresTcpSocket(Formatter, task.AcceptSocket)));
                }
            }

            if (socket != null)
            {
                socket.QueueAccept(task);
            }
        }
예제 #13
0
        private void ReceiveCompleted(object sender, IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            if (e.Task.Exception == null)
            {
                if (e.Task.Transferred > 0)
                {
                    Monitor.AddInput(e.Task.Transferred);

                    if ((bool)e.Task.UserToken)
                    {
                        e.Task.UserToken = false;

                        ushort length = BitConverter.ToUInt16(e.Buffer.Buffer, e.Buffer.Offset);

                        // Ares has a hard message limit of 4k... enforce?

                        if (length > (SocketManager.BufferSize - 1))
                        {
                            throw new SocketException((int)SocketError.NoBufferSpaceAvailable);
                        }

                        e.Task.Count = length + 1;
                        socket.QueueReceive(e.Task);
                    }
                    else
                    {
                        e.Task.UserToken = true;

                        byte id = e.Buffer.Buffer[e.Buffer.Offset];
                        OnPacketReceived(id, e.Buffer.Buffer, e.Buffer.Offset + 1, e.Task.Transferred - 1);

                        e.Task.Count = 2;
                        if (Connected)
                        {
                            socket.QueueReceive(e.Task);
                        }
                    }
                }
            }
            else
            {
                OnException(e.Task.Exception);
            }
        }
예제 #14
0
        private void SendComplete(object sender, IOTaskCompleteEventArgs <SocketSendTask> e)
        {
            e.Task.Completed -= sendHandler;

            if (e.Task.Exception == null)
            {
                Monitor.AddOutput(e.Task.Transferred);

                try {
                    var msg = (IPacket)e.Task.UserToken;
                    PacketSent?.Invoke(this, new PacketEventArgs(msg, WebSocketMessageType.Binary, e.Task.Transferred, e.Task.RemoteEndPoint));
                }
                catch (Exception ex) {
                    OnException(ex, e.Task.RemoteEndPoint);
                }
            }
            else
            {
                OnException(e.Task.Exception, e.Task.RemoteEndPoint);
            }
        }
예제 #15
0
        protected virtual void ReceiveCompleted(object sender, IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            if (e.Task.Exception == null)
            {
                if (e.Task.Transferred > 0)
                {
                    Monitor.AddInput(e.Task.Transferred);
                    try {
                        switch (State)
                        {
                        case ReceiveStatus.Header:
                            HandlePacketHeader(e);
                            break;

                        case ReceiveStatus.Request_Head:
                            HandleRequestHeader(e);
                            break;

                        case ReceiveStatus.Request_Body:
                            HandleRequestBody(e);
                            break;

                        case ReceiveStatus.Decode_Length:
                            HandleWebSocketLength(e);
                            break;

                        case ReceiveStatus.Payload: {
                            HandlePayload(e);
                            break;
                        }
                        }
                    }
                    catch (Exception ex) { OnException(ex); }
                }
            }
            else
            {
                OnException(e.Task.Exception);
            }
        }
예제 #16
0
        protected virtual void HandlePayload(IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            int mask_length = 0;

            if (IsWebSocket)
            {
                var state = (WebSocketReceiveState)e.Task.UserToken;
                if (state.IsMasking)
                {
                    mask_length = 4;
                    //+1 for not copying the buffer to do the unmasking!
                    for (int i = 4; i < e.Task.Transferred; i++)
                    {
                        e.Buffer.Buffer[e.Buffer.Offset + i] ^= e.Buffer.Buffer[e.Buffer.Offset + (i % 4)];
                    }
                }

                switch (state.OpCode)
                {
                case WebSocketOpCode.Text: {
                    using var s      = new MemoryStream(e.Buffer.Buffer, e.Buffer.Offset + mask_length, e.Task.Transferred - mask_length);
                    using var reader = new PacketReader(s);

                    string tmp   = reader.ReadString();
                    Match  match = Regex.Match(tmp, "[a-z]+?:", RegexOptions.Singleline | RegexOptions.IgnoreCase);

                    if (match.Success)
                    {
                        //is ib0t message
                        Isib0tSocket = true;
                        MessageType  = WebSocketMessageType.Text;
                        Handleib0tMessage(tmp, e.Task.Transferred);
                        ReceiveAsyncInternal(e.Task);
                        return;
                    }
                    else
                    {
                        int id = tmp.ExtractId();
                        if (id > -1)
                        {
                            MessageType = WebSocketMessageType.Text;
                            OnTextPacketReceived((byte)id, tmp, e.Task.Transferred);
                            ReceiveAsyncInternal(e.Task);
                            return;
                        }
                    }

                    //this is a message type we don't recongnize.
                    Disconnect(WebSocketCloseStatus.InvalidPayloadData);
                    return;
                }

                case WebSocketOpCode.Ping:
                    //PingPongPacket was initially a private item and handled internally
                    //however I decided that it can eventually get checked by AresServer for IO monitoring and flood inspecting
                    byte[] buffer = new byte[e.Task.Transferred - mask_length];
                    Array.Copy(e.Buffer.Buffer, e.Buffer.Offset, buffer, 0, buffer.Length);

                    var ping = new PingPongPacket(buffer);

                    OnBinaryPacketReceived(ping, e.Task.Transferred);
                    SendAsync(ping);

                    ReceiveAsyncInternal(e.Task);
                    return;

                case WebSocketOpCode.Pong:
                    ReceiveAsyncInternal(e.Task);
                    return;

                case WebSocketOpCode.Binary:
                    MessageType = WebSocketMessageType.Binary;
                    break;  //let binary fall through below

                default:    //don't handle any of the other opcodes right now
                    Disconnect(WebSocketCloseStatus.InvalidMessageType);
                    return;
                }
            }

            OnBinaryPacketReceived(
                e.Buffer.Buffer[e.Buffer.Offset + mask_length],
                e.Buffer.Buffer,
                e.Buffer.Offset + mask_length + 1,
                e.Task.Transferred - mask_length - 1
                );

            ReceiveAsyncInternal(e.Task);
        }
예제 #17
0
        protected virtual void HandleRequestHeader(IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            var token = (HttpRequestState)e.Task.UserToken;

            token.Buffer.AddRange(e.Buffer.Buffer.Skip(e.Buffer.Offset).Take(e.Task.Transferred));
            string temp = Encoding.UTF8.GetString(token.Buffer.ToArray());

            int terminator = temp.IndexOf("\r\n\r\n");

            if (terminator == -1)
            {
                //still need the rest of the header
                if (Socket.Available == 0)
                {
                    //no data available... wait longer?
                }
                e.Task.UserToken = token;
                e.Task.Count     = Socket.Available;
                if (IsConnected)
                {
                    Socket.QueueReceive(e.Task);
                }
            }
            else
            {
                string header = temp.Substring(0, terminator);
                string body   = temp.Substring(terminator + 4);

                //remove up-to the body from the buffer
                token.Total = token.Buffer.Count;
                token.Buffer.RemoveRange(0, Encoding.UTF8.GetByteCount(header) + 4);

                int      contentLen = 0;
                string[] lines      = header.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

                Match match = Regex.Match(lines[0], "(\\S+)\\s+/(\\S*)\\s+(\\S*)");
                if (match.Success)
                {
                    token.Method     = match.Groups[1].Value;
                    token.RequestUri = match.Groups[2].Value;
                    token.Protocol   = match.Groups[3].Value;

                    for (int i = 1; i < lines.Length; i++)
                    {
                        match = Regex.Match(lines[i], "\\s*(\\S+)\\s*:\\s*(\\S+)");
                        if (match.Success)
                        {
                            string key   = match.Groups[1].Value.ToUpper();
                            string value = match.Groups[2].Value;
                            switch (key)
                            {
                            case "CONTENT-LENGTH":
                                int.TryParse(value, out contentLen);
                                break;

                            case "SEC-WEBSOCKET-PROTOCOL":
                                break;
                            }
                            token.Headers.Add(key, value);
                        }
                    }

                    if (contentLen > 0 && token.Buffer.Count < contentLen)
                    {
                        //body is incomplete
                        State            = ReceiveStatus.Request_Body;
                        e.Task.UserToken = token;
                        e.Task.Count     = (contentLen - token.Buffer.Count);

                        if (IsConnected)
                        {
                            Socket.QueueReceive(e.Task);
                        }
                    }
                    else
                    {
                        token.Content = body;
                        OnHttpRequestReceived(token);
                        ReceiveAsyncInternal(e.Task);
                    }
                }
                else
                {
                    Disconnect();
                }
            }
        }
예제 #18
0
        protected virtual void HandlePacketHeader(IOTaskCompleteEventArgs <SocketReceiveTask> e)
        {
            if (IsWebSocket)  //receive encoded message
            {
                byte first = e.Buffer.Buffer[e.Buffer.Offset];

                /*support multi-part frames?
                 * bool fin =  (first & (1 << 7)) != 0;
                 * bool rsv1 = (first & (1 << 6)) != 0;
                 * bool rsv2 = (first & (1 << 5)) != 0;
                 * bool rsv3 = (first & (1 << 4)) != 0;
                 */

                var opcode = (WebSocketOpCode)(first & ((1 << 4) - 1));
                if (opcode == WebSocketOpCode.Close)
                {
                    Disconnect();
                    return;
                }

                byte second = e.Buffer.Buffer[e.Buffer.Offset + 1];

                int  length = second & 127;
                bool masked = (second & (1 << 7)) != 0;

                if (!masked && should_mask)
                {
                    //MASKED BIT NOT SET
                    Disconnect(WebSocketCloseStatus.ProtocolError);
                    return;
                }

                e.Task.UserToken = new WebSocketReceiveState {
                    OpCode    = opcode,
                    IsMasking = masked
                };

                switch (length)
                {
                case 126:    //ushort
                    State        = ReceiveStatus.Decode_Length;
                    e.Task.Count = 2;
                    break;

                case 127:    //ulong
                    State        = ReceiveStatus.Decode_Length;
                    e.Task.Count = 8;
                    break;

                default:
                    State        = ReceiveStatus.Payload;
                    e.Task.Count = masked ? length + 4: length;
                    break;
                }
            }
            else
            {
                ushort length = BitConverter.ToUInt16(e.Buffer.Buffer, e.Buffer.Offset);

                // Ares has a hard message limit of 4k... enforce?
                // Zorbo uses a *default* socket buffer of 8k
                // Anything larger than this is either special or an error
                if (length == 17735 || //Numerical equivalent of "GE"
                    length == 17736 || //"HE"
                    length == 20304)   //"PO"

                {
                    var token = new HttpRequestState();
                    token.Buffer.AddRange(e.Buffer.Buffer.Skip(e.Buffer.Offset).Take(2));

                    State            = ReceiveStatus.Request_Head;
                    e.Task.UserToken = token;
                    e.Task.Count     = length == 17735 ? 3 : 4;//need to receive rest of request from stream
                }
                else
                {
                    if (length >= SocketManager.BufferSize)
                    {
                        throw new SocketException((int)SocketError.NoBufferSpaceAvailable);
                    }

                    State        = ReceiveStatus.Payload;
                    e.Task.Count = length + 1;
                }
            }
            //we got this far, keep receiving
            if (IsConnected)
            {
                Socket.QueueReceive(e.Task);
            }
        }
예제 #19
0
 private void ConnectCompleted(object sender, IOTaskCompleteEventArgs <SocketConnectTask> args)
 {
     args.Task.Completed -= ConnectCompleted;
     ((Action <ISocket>)args.Task.UserToken)(this);
 }
예제 #20
0
 protected virtual void ConnectCompleted(object sender, IOTaskCompleteEventArgs <SocketConnectTask> e)
 {
     e.Task.Completed -= ConnectCompleted;
     Connected?.Invoke(this, new ConnectEventArgs(e.Task.UserToken));
 }