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); } } }
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); } }
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); } }
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); } }
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); } }
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)); }
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)); } }
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); } }
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); }
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(); }
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; } }
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); } }
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); } }
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); } }
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); } }
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); }
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(); } } }
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); } }
private void ConnectCompleted(object sender, IOTaskCompleteEventArgs <SocketConnectTask> args) { args.Task.Completed -= ConnectCompleted; ((Action <ISocket>)args.Task.UserToken)(this); }
protected virtual void ConnectCompleted(object sender, IOTaskCompleteEventArgs <SocketConnectTask> e) { e.Task.Completed -= ConnectCompleted; Connected?.Invoke(this, new ConnectEventArgs(e.Task.UserToken)); }