예제 #1
0
        virtual internal void OnNewConnection(INetworkNode Remote)
        {
            if (Remote == null)
            {
                return;
            }

            if (!Remotes.Contains(Remote))
            {
                Remotes.Add(Remote);
            }

            if (NewConnection == null)
            {
                return;
            }

            Task.Run(() =>
            {
                NewConnection?.Invoke(this, new InternetConnectionEventArgs
                {
                    Local  = this,
                    Remote = Remote
                });
            });
        }
예제 #2
0
파일: CQHub.cs 프로젝트: wilson0x4d/shenc
        public async Task <CQConnection> ConnectTo(string hostport)
        {
            var parts      = hostport.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
            var hostName   = parts[0];
            var portNumber = parts.Length > 1 ? int.Parse(parts[1]) : 18593;

            var connection = await CQConnection.Create(_crypt, hostName, portNumber, _rsa, _onStatusChange);

            ValidateWhitelistAndSetAlias(connection);

            lock (_connections)
            {
                // NOTE: prior connections to same peer are not removed, by design
                _connections.Add(connection);
            }
            try
            {
                NewConnection?.Invoke(this, new CQConnectionEventArgs
                {
                    Connection = connection
                });
            }
            catch (Exception ex)
            {
                ex.Log();
            }
            $"Connected to [{connection}]".Log();

            return(connection);
        }
예제 #3
0
        /// <summary>
        /// Adds to the Inbound Requests que and adds to the connections list if a matching IP does not exist.
        /// </summary>
        /// <param name="from">IPAddress of the request</param>
        private static void AddInboundRequest(object from)
        {
            IPAddress sender = (IPAddress)from;
            bool      found  = false;

            foreach (ConnectionInfo connection in connections)
            {
                if (connection.address.Equals(sender))
                {
                    found = true;
                    if (!InboundReq.Contains(connection))
                    {
                        InboundReq.Add(connection);
                        connection.InvokeInboundRequest();
                    }
                    else if (OutboundReq.Contains(connection))
                    {
                        GameConnection.RequestGame(connection);
                    }
                    break;
                }
            }

            if (found == false && NewConnection != null)
            {
                ConnectionInfo connection = new ConnectionInfo()
                {
                    address = sender, displayName = "Unknown"
                };
                connections.Add(connection);
                InboundReq.Add(connection);
                NewConnection.Invoke(null, connection);
                connection.InvokeInboundRequest();
            }
        }
예제 #4
0
        /*接收新的连接*/
        private void OnAcceptNewConnection(object sender, SocketAsyncEventArgs e)
        {
            /*新连接的socket对象*/
            var socket = e.AcceptSocket;

            /*继续接收*/
            startAccept(e);

            /*连接数+1*/
            Interlocked.Increment(ref connectionCount);


            /*尝试取出一个异步完成套接字*/
            if (!receiveAsyncEventQueue.TryDequeue(out var socketReceiveAsync))
            {
                socketReceiveAsync            = new SocketAsyncEventArgs();
                socketReceiveAsync.Completed += SocketAsync_Receive_Completed;
                socketReceiveAsync.SetBuffer(new byte[bufferLength], 0, bufferLength);
            }

            /*创建一个客户端*/
            var connection = new SocketClient
            {
                SocketAsyncEvent = socketReceiveAsync,
                RemoteEndPoint   = socket.RemoteEndPoint,
                Socket           = socket,
            };

            socketReceiveAsync.UserToken = connection;
            NewConnection?.Invoke(this, connection);
            StartReceive(connection);
        }
예제 #5
0
        async Task ConnectionWaitAsync()
        {
            _logger.LogInformation("Server: Waiting for connection");
            if (_listener is null)
            {
                return;
            }
            var tcs = new TaskCompletionSource <int>();

            await using (Token.Register(tcs.SetCanceled))
            {
                while (!Token.IsCancellationRequested)
                {
                    var t = _listener.AcceptTcpClientAsync();
                    if ((await Task.WhenAny(t, tcs.Task)).IsCanceled)
                    {
                        break;
                    }
                    try
                    {
                        using var client = t.Result;
                        var message = await JsonSerializer.DeserializeAsync <Message>(client.GetStream());

                        var endPoint = client.Client.RemoteEndPoint;
                        await(NewConnection?.Invoke(endPoint as IPEndPoint, message.Type) ?? Task.CompletedTask);
                        await(MessageReceived?.Invoke(message, endPoint as IPEndPoint) ?? Task.CompletedTask);
                    }
                    catch (SocketException e)
                    {
                        _logger.LogError("Server: Error on ConnectionWaiting.", e);
                    }
                }
            }
            _listener.Stop();
        }
예제 #6
0
        private void StartListenRequests()
        {
            _logger.Trace("Запуск прослушивания подключений...");

            while (true)
            {
                try
                {
                    var    handler = _serverSocket.Accept();
                    var    builder = new StringBuilder();
                    int    bytes   = 0;
                    byte[] data    = new byte[256];

                    do
                    {
                        bytes = handler.Receive(data);
                        builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                    }while (handler.Available > 0);

                    _logger.Trace("Обнаружено новое подключение...");

                    var message = builder.ToString();
                    NewConnection?.Invoke(message, handler);
                }
                catch (Exception e)
                {
                    _logger.Error($"Произошла ошибка при получении запроса: {e.Message}");
                }
            }
        }
예제 #7
0
        public async Task ReceiveMessagesUntilCloseAsync()
        {
            try
            {
                NewConnection?.Invoke(this, EventArgs.Empty);
                byte[] receivePayloadBuffer = new byte[_receivePayloadBufferSize];
                WebSocketReceiveResult webSocketReceiveResult =
                    await _webSocket.ReceiveAsync(new ArraySegment <byte>(receivePayloadBuffer),
                                                  CancellationToken.None);

                CloseStatus = await GetMessage(webSocketReceiveResult);

                CloseStatusDescription = webSocketReceiveResult.CloseStatusDescription;
            }
            catch (WebSocketException webSocketException) when(webSocketException
                                                               .WebSocketErrorCode ==
                                                               WebSocketError.ConnectionClosedPrematurely)
            {
                Console.WriteLine(
                    "connection ConnectionClosedPrematurely (exception is catch-ed) ");
            }
            catch (OperationCanceledException)
            {
                // Happens when the application closes
                Console.WriteLine("connection OperationCanceledException (exception is catch-ed)");
            }
        }
예제 #8
0
 private void HandshakeFinished(IAsyncResult status)
 {
     TrySocketAction(r =>
     {
         r.EndSend(status);
         r.BeginReceive(ReceivedDataBuffer, 0, ReceivedDataBuffer.Length, 0, new AsyncCallback(Read), null);
         NewConnection?.Invoke(this, EventArgs.Empty);
     });
 }
예제 #9
0
 public Task NewConnectionAsync(Connection connection)
 {
     Workload();
     if (NewConnection == null)
     {
         return(Task.CompletedTask);
     }
     return(NewConnection?.Invoke(connection));
 }
예제 #10
0
        private void HandleConnectionPacket(TcpPacket tcpPacket, ConnectionId connectionId)
        {
            var connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber);

            NewConnection?.Invoke(connection);

            if (connection.HasSubscribers)
            {
                _connections[connectionId] = connection;
            }
        }
예제 #11
0
        public Task NewConnectionAsync(ObjectPath device, CloseSafeHandle fileDescriptor, IDictionary <string, object> properties)
        {
            SocketState     = SocketStates.Connected;
            _fileDescriptor = fileDescriptor;
            Log.Debug("Linux.BluetoothSocket: Connected to profile");

            Stream = new UnixStream(fileDescriptor.DangerousGetHandle().ToInt32());

            Task.Run(() => NewConnection?.Invoke(device, _fileDescriptor, properties));
            return(Task.CompletedTask);
        }
예제 #12
0
        private void HandleTcpDataReceived(TcpConnection connection, ArraySegment <byte> data)
        {
            if (data.Count == 0)
            {
                return;
            }
            if (_isNew.Contains(connection))
            {
                if (_serversByIp.ContainsKey(connection.Source.Address.ToString()) &&
                    data.Array.Skip(data.Offset).Take(4).SequenceEqual(new byte[] { 1, 0, 0, 0 }))
                {
                    _isNew.Remove(connection);
                    var server = _serversByIp[connection.Source.Address.ToString()];
                    _serverToClient = connection;
                    _clientToServer = null;

                    _decrypter = new ConnectionDecrypter();
                    _decrypter.ClientToServerDecrypted += HandleClientToServerDecrypted;
                    _decrypter.ServerToClientDecrypted += HandleServerToClientDecrypted;

                    _messageSplitter = new MessageSplitter();
                    _messageSplitter.MessageReceived += HandleMessageReceived;
                    NewConnection?.Invoke(server);
                }
                if (_serverToClient != null && _clientToServer == null &&
                    (_serverToClient.Destination.Equals(connection.Source) &&
                     _serverToClient.Source.Equals(connection.Destination)))
                {
                    _isNew.Remove(connection);
                    _clientToServer = connection;
                }
            }

            if (!(connection == _clientToServer || connection == _serverToClient))
            {
                return;
            }
            if (_decrypter == null)
            {
                return;
            }
            var dataArray = data.Array.Skip(data.Offset).Take(data.Count).ToArray();

            if (connection == _clientToServer)
            {
                _decrypter.ClientToServer(dataArray);
            }
            else
            {
                _decrypter.ServerToClient(dataArray);
            }
        }
예제 #13
0
 virtual internal void OnNewConnection(INetworkNode Remote)
 {
     if (NewConnection != null)
     {
         Task.Run(() =>
         {
             NewConnection?.Invoke(this, new InternetConnectionEventArgs
             {
                 Local  = this,
                 Remote = Remote
             });
         });
     }
 }
예제 #14
0
        private void AcceptConnectCallback(IAsyncResult ar)
        {
            Listener = (Socket)ar.AsyncState;

            //acknowledge the connection
            Socket incomingSocket = null;

            try
            {
                incomingSocket = Listener.EndAccept(ar);
            }
            catch
            {
                ReportError?.Invoke("EndAccept failed on incoming connection", "");
            }

            //put the listener back to listening
            Listener.BeginAccept(new AsyncCallback(AcceptConnectCallback), Listener);

            if (incomingSocket == null)
            {
                return;
            }
            IPEndPoint ep = (IPEndPoint)incomingSocket.RemoteEndPoint;

            TConnection C = new TConnection();

            C.Setup(incomingSocket, ep.Address, ep.Port, ConnectionBufSize);

            if (AllConnections.ContainsKey(C.Address) == false)
            {
                AllConnections.Add(C.Address, C);
                AllConnectionsList.Add(C);
            }

            //Signal that a new connection has been created
            NewConnection?.Invoke(C);

            //configure the socket to receive incoming data and arm the data reception event
            try
            {
                C.ConnectionSocket.BeginReceive(C.IncomingData, 0, C.IncomingData.Length, 0, new AsyncCallback(ReadCallback), C.Address);
            }
            catch
            {
                ReportError?.Invoke("BeginReceive failed on new connection", C.Address);
            }
        }
예제 #15
0
파일: Server.cs 프로젝트: webconfig/Ballz
        public void Update(GameTime time)
        {
            NetIncomingMessage im;

            while ((im = Peer.ReadMessage()) != null)
            {
                switch (im.MessageType)
                {
                case NetIncomingMessageType.StatusChanged:
                    NetConnectionStatus status = (NetConnectionStatus)im.ReadByte();

                    string reason = im.ReadString();

                    if (!GameRunning && status == NetConnectionStatus.Connected)
                    {
                        Sync.AddConnection(im.SenderConnection);
                        NewConnection?.Invoke(this, im.SenderConnection);
                    }

                    break;

                case NetIncomingMessageType.DiscoveryRequest:
                    // Respond to discovery requests with a json-serialized game info
                    // But only send the non-secret parts
                    var publicInfo     = GameInfo.PublicInfo();
                    var serializedInfo = JsonConvert.SerializeObject(publicInfo);
                    var response       = Peer.CreateMessage();
                    response.Write(serializedInfo);
                    Peer.SendDiscoveryResponse(response, im.SenderEndPoint);
                    break;

                case NetIncomingMessageType.Data:
                    Sync.ReadMessage(im);
                    break;
                }

                Peer.Recycle(im);
            }

            if (GameRunning && WorldSyncTimer.ElapsedMilliseconds > Network.WorldSyncIntervalMs)
            {
                // Send full world state on every frame.
                //Todo: Only send updates for world synchronization
                SendWorldState();
                WorldSyncTimer.Restart();
            }
        }
예제 #16
0
        protected void AcceptHandler(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            _connAccepted.Set();

            // Get the socket that handles the client request.
            Socket clientSock = this._socket.EndAccept(ar);

            _logger.Debug($"Client connected from {clientSock.RemoteEndPoint}");

            // Create client
            InputConnection client = new InputConnection(clientSock);

            // Emit events and run default class handler
            this.OnConnection(client);
            NewConnection?.Invoke(client);
        }
예제 #17
0
파일: Controller.cs 프로젝트: smeoow/Naive
 private void onConnectionBegin(InConnection inc, IAdapter outAdapter)
 {
     if (LoggingLevel <= Logging.Level.None)
     {
         debug($"'{inc.InAdapter.Name}' {inc} -> '{outAdapter.Name}'");
     }
     try {
         lock (InConnectionsLock) {
             inc.InAdapter.GetAdapter().CreatedConnections++;
             _totalHandledConnections++;
             InConnections.Add(inc.Id, inc);
             NewConnection?.Invoke(inc);
         }
     } catch (Exception e) {
         Logger.exception(e, Logging.Level.Error, "event NewConnection");
     }
 }
예제 #18
0
        private void InitialiseSocketHandler(TcpClient socket)
        {
            var handler = new FtpSocketHandler(m_fileSystemClassFactory, m_nId);

            handler.UserLoginEvent  += UserLoginEvent;
            handler.UserLogoutEvent += UserLogoutEvent;
            // get encoding for the socket connection
            handler.Start(socket, m_encoding);

            m_apConnections.Add(handler);

            numberOfConnections = m_apConnections.Count;

            Trace.WriteLine($"Add a new handler, current connection number is {numberOfConnections}", "Information");

            handler.Closed += Handler_Closed;

            NewConnection?.Invoke(m_nId);
        }
예제 #19
0
        protected virtual ServerPlayer AcceptTCPConnection(TCPConnectionManager.PendingClient client)
        {
            ServerPlayer p = NewPlayerRecord(client);

            Logger.Log3("Socket " + p.GetTCPRemoteAddresString() + " Connected ");

            p.Disconnected += P_Disconnected;

            p.PlayerID = FindPlayerID();
            if (p.PlayerID < 0)
            {
                return(null);
            }

            lock (ConnectedPlayers)
                ConnectedPlayers.Add(p.PlayerID, p);

            NewConnection?.Invoke(this, p);

            return(p);
        }
예제 #20
0
        private void InitialiseSocketHandler(TcpClient socket)
        {
            lock (m_apConnections)
            {
                var handler = new FtpSocketHandler(m_fileSystemClassFactory, m_nId);
                handler.Closed += handler_Closed;

                // get encoding for the socket connection

                handler.Start(socket, m_encoding);

                m_apConnections.Add(handler);

                FtpServer.LogWrite(
                    $"Client accepted: {socket.Client.RemoteEndPoint} current count={m_apConnections.Count}");
                Trace.WriteLine(
                    $"Handler created for client {handler.RemoteEndPoint}. Current Count {m_apConnections.Count}",
                    "Information");

                NewConnection?.Invoke(m_nId);
            }
        }
예제 #21
0
파일: CQHub.cs 프로젝트: wilson0x4d/shenc
        public async Task OnConnectionAccepted(TcpClient tcpClient)
        {
            var connection = await CQConnection.Create(
                _crypt,
                tcpClient,
                _rsa,
                _onStatusChange);

            connection.ConversationEnded += (s, e) =>
            {
                lock (_connections)
                {
                    if (_connections.Remove(connection))
                    {
                        $"Removed {connection}".Log();
                    }
                }
            };

            ValidateWhitelistAndSetAlias(connection);

            $"Accepted [{connection}]".Log();
            lock (_connections)
            {
                _connections.Add(connection);
                try
                {
                    NewConnection?.Invoke(this, new CQConnectionEventArgs
                    {
                        Connection = connection
                    });
                }
                catch (Exception ex)
                {
                    ex.Log();
                }
            }
        }
예제 #22
0
        public async void AcceptConnections()
        {
            try
            {
                _running = true;
                _tcpServer.Start();
                while (_running)
                {
                    var client = await _tcpServer.AcceptTcpClientAsync();

                    //Console.WriteLine("SERVER:" + client.Client.RemoteEndPoint.ToString());
                    var ch = new ClientHandler(_decoder, client);
                    ch.WunderPacketReceived += WunderPacketClientReceived;
                    _clients.Add(ch);
                    NewConnection?.Invoke(ch);
                }
                _tcpServer.Stop();
            }
            catch
            {
                _running = false;
                Console.WriteLine("Connections Closed");
            }
        }
예제 #23
0
 protected virtual void OnNewConnection(NewConnectionHandlerArgs e)
 {
     NewConnection?.Invoke(this, e);
 }
예제 #24
0
 protected virtual void OnNewConnection(Socket handler)
 {
     NewConnection?.Invoke(this, new SocketNewConnectionEventArgs(handler));
 }
예제 #25
0
        private void EstablishConnection(Socket client)
        {
            Task.Run(async() =>
            {
                var stream = new NetworkStream(client);

                // Handshake/upgrade connection
                while (!stream.DataAvailable && !_cts.IsCancellationRequested)
                {
                }
                _cts.Token.ThrowIfCancellationRequested();

                byte[] buffer = new byte[client.Available];
                await stream.ReadAsync(buffer, 0, buffer.Length, _cts.Token);

                // GET // HTTP/1.1
                // Pragma: no-cache
                // Cache-Control: no-cache
                // Host: 127.0.0.1
                // Origin: http://127.0.0.1
                // Upgrade: websocket
                // Connection: Upgrade
                // Sec-WebSocket-Key: <base64 encoded key>
                // Sec-WebSocket-Protocol: xmpp
                // Sec-WebSocket-Version: 13

                string wsKeyHash     = null;
                string authorization = null;
                string[] request     = Encoding.UTF8.GetString(buffer).Split(new [] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string line in request)
                {
                    if (line.StartsWith("Sec-WebSocket-Key"))
                    {
                        string wsKey = line.Substring(line.IndexOf(' ') + 1);
                        wsKey       += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // magic
                        wsKeyHash    = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(wsKey)));
                    }

                    if (line.StartsWith("Authorization"))
                    {
                        authorization = line.Substring(line.IndexOf(' ') + 1);
                    }
                }

                var responseBuilder = new StringBuilder();
                responseBuilder.Append("HTTP/1.1 101 Switching Protocols\r\n");
                responseBuilder.Append("Connection: upgrade\r\n");
                responseBuilder.Append("Upgrade: websocket\r\n");
                responseBuilder.Append("Sec-WebSocket-Accept: " + wsKeyHash + "\r\n");
                responseBuilder.Append("\r\n");
                byte[] response = Encoding.UTF8.GetBytes(responseBuilder.ToString());
                await stream.WriteAsync(response, 0, response.Length);
                await stream.FlushAsync();

                // Since we'll be using this task to receive incoming messages, we'll raise the
                // new connection event in a different task.
                var raiseEventTask = Task.Run(() =>
                {
                    NewConnection?.Invoke(this, new WebsocketMessageNewConnectionEventArgs(client, authorization));
                });

                // Handshake complete, now decode incoming messages.
                while (!_cts.IsCancellationRequested)
                {
                    while (!stream.DataAvailable && !_cts.IsCancellationRequested)
                    {
                    }
                    _cts.Token.ThrowIfCancellationRequested();

                    buffer = new byte[client.Available];
                    await stream.ReadAsync(buffer, 0, buffer.Length, _cts.Token);

                    string byteString = BitConverter.ToString(buffer).Replace("-", " ");

                    var message = new WebsocketMessage(buffer);
                    if (_messageFragments.Count > 0)
                    {
                        _messageFragments.Add(message);

                        if (message.IsCompleted)
                        {
                            // Combine all message fragments.
                            message = WebsocketMessage.Defragment(_messageFragments);
                            _messageFragments.Clear();

                            MessageReceived?.Invoke(this, new WebsocketMessageReceivedEventArgs(client, message));
                        }
                    }
                    else
                    {
                        if (message.IsCompleted)
                        {
                            MessageReceived?.Invoke(this, new WebsocketMessageReceivedEventArgs(client, message));
                        }
                        else
                        {
                            _messageFragments.Add(message);
                        }
                    }
                }
            });
        }
예제 #26
0
 private void OnNewConnection(Connection connection)
 {
     NewConnection?.Invoke(this, connection);
 }
예제 #27
0
 private void OnNewConnection(ServerPeer arg1, Connection arg2)
 {
     NewConnection?.Invoke(arg1, arg2);
 }
예제 #28
0
 protected virtual void NewConnectionEvent(MessageEventArgs e)
 {
     NewConnection?.Invoke(this, e);
 }
예제 #29
0
        /// <summary>
        /// Start listening for clients.
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public async Task Listen(int port)
        {
            lock (_startStopLockObject)
            {
                Port = port;
                _logger.LogInformation($"Starting listen on TCP port {Port}");
                if (Listening)
                {
                    throw new Exception("Already listening.");
                }
                Listening = true;
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = new CancellationTokenSource();
                _tcpListener             = new TcpListener(IPAddress.Any, Port);
                _tcpListener.Start();
            }

            for (; ;)
            {
                // Wait for connection
                Socket socket = null;
                var    tcpl   = _tcpListener;
                if (tcpl == null)
                {
                    break;
                }
                try
                {
                    socket = await tcpl.AcceptSocketAsync();
                }
                catch (ObjectDisposedException)
                {
                    // Socket is disposed, most likely because we called Stop
                    if (_cancellationTokenSource.Token.IsCancellationRequested)
                    {
                        break;
                    }
                    // No?
                    throw;
                }

                if (socket == null || _cancellationTokenSource.Token.IsCancellationRequested)
                {
                    break;
                }

                var rd = new RequestDetails()
                {
                    RemoteEndpoint = socket.RemoteEndPoint,
                    AcceptRequest  = true
                };
                try
                {
                    ConnectionRequest?.Invoke(this, rd);
                }
                catch (Exception exception)
                {
                    _logger.LogError(exception, "ConnectionRequest event handler threw exception. Disposing of socket safely, effectively ignoring incoming connection.");
                    socket.Close(10);
                    socket.Dispose();
                    continue;
                }

                if (!rd.AcceptRequest)
                {
                    _logger.LogInformation($"Denied new client connection on TCP port {Port} from {((IPEndPoint)socket.RemoteEndPoint).Address}:{((IPEndPoint)socket.RemoteEndPoint).Port}");
                    socket.Close(10);
                    socket.Dispose();
                    continue;
                }

                // Got new connection, create a protocol handler for it and fire off event
                var client = new NmpTcpClient(_logger, socket, _maxClientPacketSize);
                _logger.LogInformation($"Accepted new client connection on TCP port {Port} from {((IPEndPoint)socket.RemoteEndPoint).Address}:{((IPEndPoint)socket.RemoteEndPoint).Port}");
                NewConnection?.Invoke(this, client);
            }

            _logger.LogInformation($"Ended listening on TCP port {Port}");
        }
예제 #30
0
        public void Start()
        {
            if (_active)
            {
                throw new InvalidOperationException("Already active");
            }

            _active = true;

            Task.Run(async() =>
            {
                while (_active)
                {
                    var datagram = await _udp.ReceiveAsync().ConfigureAwait(false);
                    var data     = datagram.Buffer;
                    var endpoint = datagram.RemoteEndPoint;

                    if (data.Length <= 2)
                    {
                        if (data[0] != (byte)MessageIdentifiers.OpenConnectionRequest)
                        {
                            continue;
                        }

                        if (!_connections.ContainsKey(endpoint))
                        {
                            _connections[endpoint] = new ReliabilityLayer(_udp, endpoint);
                        }

                        var conn = _connections[endpoint];

                        if (!conn.Active)
                        {
                            conn.StartSendLoop();
                        }

                        var pkt = new byte[] { (byte)MessageIdentifiers.OpenConnectionReply, 0 };

                        await _udp.SendAsync(pkt, pkt.Length, endpoint).ConfigureAwait(false);
                    }
                    else
                    {
                        if (!_connections.TryGetValue(endpoint, out var layer))
                        {
                            continue;
                        }

                        foreach (var packet in layer.HandleDatagram(data))
                        {
                            var stream = new BitStream(packet);

                            switch ((MessageIdentifiers)stream.ReadByte())
                            {
                            case MessageIdentifiers.ConnectionRequest:
                                _handleConnectionRequest(stream, endpoint);
                                break;

                            case MessageIdentifiers.InternalPing:
                                _handleInternalPing(stream, endpoint);
                                break;

                            case MessageIdentifiers.NewIncomingConnection:
                                NewConnection?.Invoke(endpoint);
                                break;

                            case MessageIdentifiers.DisconnectionNotification:
                                _handleDisconnection(endpoint);
                                break;

                            case MessageIdentifiers.UserPacketEnum:
                                PacketReceived?.Invoke(endpoint, packet);
                                break;
                            }
                        }
                    }
                }
            });

            Task.Run(async() =>
            {
                while (_active)
                {
                    await Task.Delay(30000);

                    var dead = _connections.Keys.Where(k =>
                    {
                        var conn = _connections[k];

                        return(conn.Resends && conn.LastAckTime < Environment.TickCount / 1000f - 10f);
                    }).ToArray();

                    for (var i = 0; i < dead.Length; i++)
                    {
                        CloseConnection(dead[i]);
                    }
                }
            });
        }