Пример #1
0
        /// <summary>
        /// Extract the first incoming packet.
        /// </summary>
        public bool ReceivePacket(out Buffer buffer, out IPEndPoint source)
        {
            if (Port == 0)
            {
                Stop();
                throw new InvalidOperationException(
                          "You must specify a non-zero port to UdpProtocol.Start() before you can receive data.");
            }

            if (inQueue.Count != 0)
            {
                lock (inQueue)
                {
                    Datagram dg = inQueue.Dequeue();
                    buffer = dg.buffer;
                    source = dg.ip;
#if DEBUG
                    Debug.Log("[UdpProtocol:ReceivePacket(" + buffer.size + ", " + source +
                              ") - Receiving packet ....");
#endif
                    if (OnPacketReceived != null)
                    {
                        OnPacketReceived.Invoke(buffer, source);
                    }

                    return(true);
                }
            }

            buffer = null;
            source = null;
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Handler for end of the begin receive call.
        /// </summary>
        /// <param name="ar">Contains the results of the receive.</param>
        private void EndReceiveFrom(IAsyncResult ar)
        {
            try
            {
                // When socket is closed the object will be disposed of in the middle of a receive.
                if (!m_isClosed)
                {
                    EndPoint remoteEP = m_addressFamily == AddressFamily.InterNetwork
                        ? new IPEndPoint(IPAddress.Any, 0)
                        : new IPEndPoint(IPAddress.IPv6Any, 0);

                    int bytesRead = m_udpSocket.EndReceiveFrom(ar, ref remoteEP);

                    if (bytesRead > 0)
                    {
                        // During experiments IPPacketInformation wasn't getting set on Linux. Without it the local IP address
                        // cannot be determined when a listener was bound to IPAddress.Any (or IPv6 equivalent). If the caller
                        // is relying on getting the local IP address on Linux then something may fail.
                        //if (packetInfo != null && packetInfo.Address != null)
                        //{
                        //    localEndPoint = new IPEndPoint(packetInfo.Address, localEndPoint.Port);
                        //}

                        byte[] packetBuffer = new byte[bytesRead];
                        Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead);
                        OnPacketReceived?.Invoke(this, m_localPort, remoteEP as IPEndPoint, packetBuffer);
                    }
                }
            }
            catch (SocketException)
            {
                // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during
                // normal RTP operation. For example:
                // - the RTP connection may start sending before the remote socket starts listening,
                // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old
                //   or new socket during the transition.
                // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur
                // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in
                // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP
                // error since the remote party may not have initialised their socket yet.
                //logger.LogWarning($"SocketException UdpReceiver.EndReceiveMessage. {sockExcp}");
            }
            catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored.
            {
            }
            catch (Exception excp)
            {
                Logger.Logger.Error($"Exception UdpReceiver.EndReceiveMessage. ->{excp}");
                Close(excp.Message);
            }
            finally
            {
                if (!m_isClosed)
                {
                    BeginReceiveFrom();
                }
            }
        }
Пример #3
0
        public virtual void ___recv___(Victem victem, string packet)
        {
            var handler = OnPacketReceived;

            if (handler != null)
            {
                OnPacketReceived?.Invoke(victem, packet);
            }
        }
Пример #4
0
        /// <summary>
        /// Manuseia Comunicação do Cliente
        /// </summary>
        private void HandleClient(object obj)
        {
            try
            {
                //Recebe cliente a partir do parâmetro
                TcpClient tcpClient = (TcpClient)obj;

                NetworkStream clientStream = tcpClient.GetStream();

                #region READ ON CONNECT INICIAL

                AuthPacket packet = ReceivePacket(clientStream);

                var client = new AuthClient(tcpClient)
                {
                    Name = packet.Message.ServerName,
                    Type = packet.Message.ServerType,
                    Key  = packet.Message.Key
                };

                Clients.Add(client);

                ClientConnected(client);

                OnPacketReceived?.Invoke(client, packet);

                #endregion

                //Escuta contínuamente as mensagens dos clientes (Servidores) enquanto estiver conectado
                while (tcpClient.Connected)
                {
                    try
                    {
                        packet = ReceivePacket(clientStream);

                        OnPacketReceived?.Invoke(client, packet);
                    }
                    catch (Exception erro)
                    {
                        Console.WriteLine(DateTime.Now.ToString() + $" Exception error:" + Environment.NewLine);
                        Console.WriteLine(erro.Message + Environment.NewLine);

                        //Desconecta client
                        DisconnectClient(client);
                    }
                }

                //Caso o Client não estiver mais conectado
                DisconnectClient(client);
            }
            catch (Exception erro)
            {
                Console.WriteLine(DateTime.Now.ToString() + $" Exception error:" + Environment.NewLine);
                Console.WriteLine(erro.Message + Environment.NewLine);
            }
        }
Пример #5
0
 private void InvokeDataReceivedEvent(Packet packet)
 {
     try
     {
         OnPacketReceived?.Invoke(packet.PacketPayload);
     }
     catch (Exception exception)
     {
         logger?.LogError(exception, "OnPacketReceived threw an exception");
     }
 }
Пример #6
0
        internal void HandlePacket(PosixTimeval timeval, TcpPacket tcp, TcpConnection connection)
        {
            OnPacketReceived?.Invoke(timeval, tcp, connection, this);

            // look for disconnection
            if (tcp.Finished == true)
            {
                IsOpen = false;

                OnFlowClosed?.Invoke(timeval, tcp, connection, this);
            }
        }
        private void MonitorStreams()
        {
            while (IsRunning)
            {
                foreach (var client in Connections.ToList())
                {
                    if (!client.IsSocketConnected())
                    {
                        var e5 = BuildEvent(client, null, String.Empty);
                        Connections.Remove(client);
                        OnConnectionRemoved?.Invoke(this, e5);
                        continue;
                    }

                    if (client.Socket.Available != 0)
                    {
                        var readObject = ReadObject(client.Socket);
                        var e1         = BuildEvent(client, null, readObject);
                        OnPacketReceived?.Invoke(this, e1);

                        if (readObject is PingPacket ping)
                        {
                            client.SendObject(ping).Wait();
                            continue;
                        }

                        if (readObject is PersonalPacket pp)
                        {
                            var destination = Connections.FirstOrDefault(c => c.ClientId.ToString() == pp.GuidId);
                            var e4          = BuildEvent(client, destination, pp);
                            OnPersonalPacketReceived?.Invoke(this, e4);

                            if (destination != null)
                            {
                                destination.SendObject(pp).Wait();
                                var e2 = BuildEvent(client, destination, pp);
                                OnPersonalPacketSent?.Invoke(this, e2);
                            }
                        }
                        else
                        {
                            foreach (var c in Connections.ToList())
                            {
                                c.SendObject(readObject).Wait();
                                var e3 = BuildEvent(client, c, readObject);
                                OnPacketSent?.Invoke(this, e3);
                            }
                        }
                    }
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Manuseia Comunicação do Cliente
        /// </summary>
        private void HandlePlayer(object obj)
        {
            //Recebe cliente a partir do parâmetro
            TcpClient tcpClient = (TcpClient)obj;

            var Player = OnConnectPlayer(tcpClient);

            var thread = new Thread(new ThreadStart(Player.RefreshData));

            thread.Start();

            //Chama evento OnClientConnected
            this.OnClientConnected?.Invoke(Player);

            while (Player.Connected)
            {
                try
                {
                    byte[] message = ReceivePacket(tcpClient.GetStream());

                    if (message.Length >= 5)
                    {
                        if (Player.Connected)
                        {
                            var packet = new Packet(message, Player.GetKey);
                            if (ShowLog)
                            {
                                packet.Log();
                            }
                            //Dispara evento OnPacketReceived
                            OnPacketReceived?.Invoke(Player, packet: packet);
                        }
                    }
                    else
                    {
                        if (Player.Connected)
                        {
                            DisconnectPlayer(Player);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ServerExpection(Player, ex);
                }
            }
            if (Player.Connected)
            {
                DisconnectPlayer(Player);
            }
        }
Пример #9
0
        private async Task Listen()
        {
            List <string> removeList = new List <string>();

            for (int i = clients.Count - 1; i >= 0; i--)
            {
                Client client = clients[i];

                if (client.IsAlive())
                {
                    Packet p = await client.Listen();

                    if (p != null)
                    {
                        PacketType type = p.GetPacketType();
                        if (type == PacketType.Identify)
                        {
                            OnUserConnect.Invoke(this, new UserConnectEventArgs(client));
                        }
                        else
                        {
                            OnPacketReceived.Invoke(this, new PacketReceivedEventArgs(client, p));
                        }
                    }
                }
                else
                {
                    await client.Stop();

                    Logger.Info($"Client dropped [{client.GetSessionId()}]");
                    clients.RemoveAt(i);
                    string sess = client.GetSessionId();

                    bool onlyone = true;
                    for (int j = clients.Count - 1; j >= 0; j--)
                    {
                        if (clients[j].GetSessionId() == sess)
                        {
                            onlyone = false;
                            break;
                        }
                    }

                    if (onlyone)
                    {
                        OnUserDisconnect.Invoke(this, new UserDosconnectEventArgs(client));
                    }
                }
            }
        }
Пример #10
0
 private void RecvThread()
 {
     while (Active)
     {
         try
         {
             var packet = Packet.FromStream(reader);
             OnPacketReceived?.Invoke(packet);
         }
         catch (Exception e)
         {
             Console.WriteLine(e);
         }
     }
 }
Пример #11
0
        /// <summary>
        /// Handler for end of the begin receive call.
        /// </summary>
        /// <param name="ar">Contains the results of the receive.</param>
        private void EndReceiveMessageFrom(IAsyncResult ar)
        {
            try
            {
                // When socket is closed the object will be disposed of in the middle of a receive.
                if (!m_isClosed)
                {
                    SocketFlags flags    = SocketFlags.None;
                    EndPoint    remoteEP = (m_udpSocket.LocalEndPoint.AddressFamily == AddressFamily.InterNetwork) ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0);

                    int bytesRead = m_udpSocket.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out var packetInfo);

                    if (bytesRead > 0)
                    {
                        IPEndPoint localEndPoint = new IPEndPoint(packetInfo.Address, (m_udpSocket.LocalEndPoint as IPEndPoint).Port);
                        byte[]     packetBuffer  = new byte[bytesRead];
                        Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead);
                        OnPacketReceived?.Invoke(this, localEndPoint, remoteEP as IPEndPoint, packetBuffer);
                    }
                }
            }
            catch (SocketException)
            {
                // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during
                // normal RTP operation. For example:
                // - the RTP connection may start sending before the remote socket starts listening,
                // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old
                //   or new socket during the transition.
                // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur
                // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in
                // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP
                // error since the remote party may not have initialised their socket yet.
            }
            catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored.
            { }
            catch (Exception excp)
            {
                logger.LogError($"Exception UdpReceiver.EndReceiveMessageFrom. {excp}");
                Close(excp.Message);
            }
            finally
            {
                if (!m_isClosed)
                {
                    BeginReceive();
                }
            }
        }
Пример #12
0
        private void OnDataReceived(IAsyncResult res)
        {
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, ReceivePort);

            byte[]    data   = client.EndReceive(res, ref ip);
            UdpPacket packet = UdpPacket.ParseData(data);

            if (packet != null)
            {
                OnPacketReceived?.Invoke(packet);
            }
            else
            {
                Console.Out.WriteLine("Bad packet received.");
            }
            client.BeginReceive(new AsyncCallback(OnDataReceived), null);
        }
Пример #13
0
        private void ReceiveLoop()
        {
            while (_alive)
            {
                int bytesRec = _socket.Receive(_buffer);

                if (_currentPacket == null)
                {
                    _currentPacket = new Packet();
                }

                if (_currentPacket.AddFragment(_buffer, bytesRec))
                {
                    OnPacketReceived?.Invoke((Packet)_currentPacket.Clone());
                    _currentPacket = null;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Manuseia Comunicação do Cliente
        /// </summary>
        private void HandlePlayer(object obj)
        {
            //Recebe cliente a partir do parâmetro
            TcpClient tcpClient = (TcpClient)obj;

            var Player = OnConnectPlayer(tcpClient);

            //Chama evento OnClientConnected
            this.OnClientConnected?.Invoke(Player);

            while (Player.Connected)
            {
                try
                {
                    byte[] message = ReceivePacket(tcpClient.GetStream());

                    if (message.Length >= 5)
                    {
                        if (Player.Connected)
                        {
                            Player.Server = this;
                            //Dispara evento OnPacketReceived
                            OnPacketReceived?.Invoke(Player, packet: new Packet(message, Player.GetKey));
                        }
                    }
                    else
                    {
                        if (Player.Connected)
                        {
                            DisconnectPlayer(Player);
                        }
                    }
                }
                catch
                {
                    DisconnectPlayer(Player);
                }
            }
            if (Player.Connected)
            {
                DisconnectPlayer(Player);
            }
        }
Пример #15
0
        /// <summary>
        /// Manuseia Comunicação do Cliente
        /// </summary>
        private void HandleClient(object obj)
        {
            //Recebe cliente a partir do parâmetro
            TcpClient tcpClient = (TcpClient)obj;

            NetworkStream clientStream = tcpClient.GetStream();

            #region READ ON CONNECT INICIAL

            AuthPacket packet = ReceivePacket(clientStream);

            var client = new AuthClient(tcpClient, packet);

            Clients.Add(client);
            Console.Title = string.Format("Pangya Fresh Up! AuthServer - LOGIN: {0}, GAMES: {1}, MESSENGER: {2}", Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.LoginServer).ToList().Count, Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.GameServer).ToList().Count, Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.MessengerServer).ToList().Count);
            ClientConnected(client);

            OnPacketReceived?.Invoke(client, packet);

            #endregion

            //Escuta contínuamente as mensagens dos clientes (Servidores) enquanto estiver conectado
            while (tcpClient.Connected)
            {
                try
                {
                    packet = ReceivePacket(clientStream);

                    OnPacketReceived?.Invoke(client, packet);
                }
                catch
                {
                    //Desconecta client
                    DisconnectClient(client);
                }
            }
            //Caso o Client não estiver mais conectado
            if (tcpClient.Connected)
            {
                DisconnectClient(client);
            }
        }
Пример #16
0
        protected async Task Init()
        {
            // Get Info
            serverInfo = await rpc.ServerInfoAsync(new ServerInfoRequest());

            // TCP relay
            tcpRelaySocket.OnPacketReceived += (buf, len) => {
                OnPacketReceived?.Invoke(buf, len);
            };
            tcpRelaySocket.Init();

            // Periodically restart listeners & reconnect
            PingTimer          = new Timer();
            PingTimer.Interval = 15000;
            PingTimer.Elapsed += PingServer;
            PingTimer.Start();

            // Sync clients periodically
            Task.Run(SyncTask);
        }
Пример #17
0
        private void HandlePacket(object obj)
        {
            //Recebe OnCliente a partir do parâmetro
            TcpClient tcpClient = (TcpClient)obj;

            var Player = OnConnectBot(tcpClient);

            //Chama evento OnClientConnected
            this.OnClientConnected?.Invoke(Player);

            while (Player.Tcp.Connected)
            {
                try
                {
                    var messageBufferRead = new byte[500000]; //Tamanho do BUFFER á ler

                    //Lê mensagem do OnCliente
                    //size =500000;
                    int bytesRead = Player.Tcp.GetStream().Read(messageBufferRead, 0, 500000);

                    //variável para armazenar a mensagem recebida
                    byte[] message = new byte[bytesRead];

                    //Copia mensagem recebida
                    Buffer.BlockCopy(messageBufferRead, 0, message, 0, bytesRead);

                    if (message.Length >= 5)
                    {
                        var packet = new ClientPacket(message);

                        OnPacketReceived?.Invoke(Player, packet);
                    }
                }
                catch (Exception ex)
                {
                    OnException(Player, ex);
                }
            }
        }
        public void Connect(IPEndPoint endPoint)
        {
            _peer.Start();
            _listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) =>
            {
                var dataPacket = new DataPacket(dataReader.RawData, dataReader.UserDataOffset, dataReader.UserDataSize,
                                                ConvertDeliveryMethod(deliveryMethod));
                OnPacketReceived?.Invoke(endPoint, dataPacket, dataReader.Recycle);
            };
            _listener.PeerConnectedEvent += peer =>
            {
                _serverPeer = peer;
                OnConnected?.Invoke(peer.EndPoint);
            };

            _listener.PeerDisconnectedEvent += (peer, info) =>
            {
                _serverPeer = null;
                using (var disconnectInfo = new LiteNetDisconnectInfo(info))
                    OnDisconnected?.Invoke(endPoint, disconnectInfo);
            };
            _peer.Connect(endPoint.Address.ToString(), endPoint.Port, "SomeConnectionKey333");
        }
Пример #19
0
        private void HandleAuthClient()
        {
            //Inicia Thread KeepAlive
            var keepAliveThread = new Thread(new ThreadStart(KeepAlive));

            keepAliveThread.Start();



            while (Tcp.Connected)
            {
                try
                {
                    var messageBufferRead = new byte[500000]; //Tamanho do BUFFER á ler

                    //Lê mensagem do cliente
                    var bytesRead = Tcp.GetStream().Read(messageBufferRead, 0, 500000);

                    //variável para armazenar a mensagem recebida
                    var message = new byte[bytesRead];

                    //Copia mensagem recebida
                    Buffer.BlockCopy(messageBufferRead, 0, message, 0, bytesRead);

                    var json = System.Text.Encoding.Default.GetString(message);

                    var response = JsonConvert.DeserializeObject <AuthPacket>(json);

                    //Dispara evento OnPacketReceived
                    OnPacketReceived?.Invoke(this, response);
                }
                catch
                {
                    OnDisconnect?.Invoke();
                }
            }
        }
Пример #20
0
        private void RecvThread()
        {
            byte[] recvBuf = new byte[4096];
            while (connected)
            {
                // Read the udp pak header ..
                int read = 0;
                while (read < 2)
                {
                    read += socket.Receive(recvBuf, read, 2, SocketFlags.None);
                }
                ushort pakSize = (ushort)((recvBuf[0] << 8) | recvBuf[1]); // << content size
                pakSize += RECV_HDR_SIZE;

                // Read the full packet
                while (read < pakSize)
                {
                    read += socket.Receive(recvBuf, read, pakSize - read, SocketFlags.None);
                }

                // Handle packet
                OnPacketReceived?.Invoke(recvBuf, pakSize);
            }
        }
Пример #21
0
 IEnumerator StartReading()
 {
     byte[] meta = new byte[sizeof(Int32)];
     while (!cts.IsCancellationRequested)
     {
         while (!cts.IsCancellationRequested && stream.DataAvailable)
         {
             var bytesRead = stream.Read(meta, 0, meta.Length);
             if (bytesRead > 0)
             {
                 var    packetSize = BitConverter.ToInt32(meta, 0);
                 byte[] data       = new byte[packetSize];
                 var    startIndex = 0;
                 while (startIndex < packetSize && !cts.IsCancellationRequested)
                 {
                     bytesRead   = stream.Read(data, startIndex, packetSize - startIndex);
                     startIndex += bytesRead;
                 }
                 OnPacketReceived?.Invoke(System.Text.Encoding.ASCII.GetString(data));
             }
         }
         yield return(new WaitForEndOfFrame());
     }
 }
Пример #22
0
 public void PacketReceived(NetworkEventArgs e)
 {
     OnPacketReceived?.Invoke(e);
 }
Пример #23
0
        private void RecvThread()
        {
            while (Active)
            {
                try
                {
                    var from       = new IPEndPoint(0, 0);
                    var recvBuffer = udpClient.Receive(ref from);
                    if (recvBuffer == null || recvBuffer.Length == 0)
                    {
                        continue;
                    }

                    NetworkPacket packet = NetworkPacket.FromByteArray(recvBuffer);
                    if ((packet.from != remoteId && packet.from != 0) || (packet.to != localId && packet.to != 0))
                    {
                        continue;
                    }
                    switch (packet.packetType)
                    {
                    case PacketType.SYN:
                    case PacketType.SYN_ACK:
                        throw new InvalidOperationException();

                    case PacketType.FIN:
                        SendRawPacket(new NetworkPacket()
                        {
                            packetType = PacketType.FIN,
                            from       = localId,
                            to         = remoteId
                        });

                        Reset();
                        break;

                    case PacketType.Raw:
                        if (packet.channel != (byte)EStreamChannel.KEstreamChannelDiscovery)
                        {
                            throw new InvalidOperationException();
                        }

                        TypedMessage            msg     = TypedMessage.FromByteArray(packet.payload);
                        EStreamDiscoveryMessage msgType = (EStreamDiscoveryMessage)msg.messageType;
                        switch (msgType)
                        {
                        case EStreamDiscoveryMessage.KEstreamDiscoveryPingRequest:
                            msg.messageType = (byte)EStreamDiscoveryMessage.KEstreamDiscoveryPingResponse;
                            SendRawPacket(new NetworkPacket()
                            {
                                packetType = PacketType.Raw,
                                from       = packet.to,
                                to         = packet.from,
                                channel    = (byte)EStreamChannel.KEstreamChannelDiscovery,
                                payload    = msg.ToByteArray()
                            });
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                        break;

                    case PacketType.Reliable:
                    case PacketType.ReliableFragment:
                    case PacketType.Unreliable:
                    case PacketType.UnreliableFragment:
                        ChannelData channelData = channels.GetOrNew(packet.channel);
                        if (!channelData.receiveQueue.ContainsKey(packet.seq))
                        {
                            channelData.receiveQueue.Add(packet.seq, packet);
                            if (packet.seq < channelData.remoteSeq)
                            {
                                Console.WriteLine("WARNING! Late packet " + packet.seq + " we are already at " + channelData.remoteSeq);
                            }
                        }
                        else
                        {
                            Console.WriteLine("WARNING! Got a resend of " + packet.seq);
                        }

                        // TODO: Clear the recv queue
                        ushort?lastValidPacketSeq      = channelData.remoteSeq > 0 ? (ushort)(channelData.remoteSeq - 1) : (ushort?)null;
                        bool   droppedIncompletePacket = false;
                        foreach (NetworkPacket firstPacket in channelData.receiveQueue.Values)
                        {
                            if (firstPacket.seq < channelData.remoteSeq)
                            {
                                continue;
                            }
                            if (firstPacket.packetType == PacketType.ReliableFragment || firstPacket.packetType == PacketType.UnreliableFragment)
                            {
                                continue;
                            }

                            // Check if the packet has all the fragments
                            bool isComplete = true;
                            for (ushort neededSeq = firstPacket.seq; neededSeq <= firstPacket.seq + firstPacket.fragment; ++neededSeq)
                            {
                                if (!channelData.receiveQueue.ContainsKey(neededSeq))
                                {
                                    isComplete = false;
                                    break;
                                }
                                else
                                {
                                    lastValidPacketSeq = neededSeq;
                                }
                            }
                            if (!isComplete)
                            {
                                // The packet is not yet fully complete
                                if (firstPacket.packetType == PacketType.Unreliable)
                                {
                                    droppedIncompletePacket = true;
                                    continue;     // this is unreliable so check if maybe next packet is complete
                                }
                                else
                                {
                                    break;     // we cannot skip any packet on reliable transports
                                }
                            }

                            if (channelData.remoteSeq != firstPacket.seq)
                            {
                                Console.WriteLine("WARNING! Dropping unreliable packets! Jump from " + channelData.remoteSeq + " to " + firstPacket.seq + (droppedIncompletePacket ? " (previous incomplete)" : ""));
                            }

                            // We have a complete packet, receive it
                            List <NetworkPacket> reassembleList = new List <NetworkPacket>();
                            for (ushort seq = firstPacket.seq; seq <= firstPacket.seq + firstPacket.fragment; ++seq)
                            {
                                if (seq != firstPacket.seq)
                                {
                                    if (firstPacket.packetType == PacketType.Reliable)
                                    {
                                        Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.ReliableFragment);
                                    }
                                    else if (firstPacket.packetType == PacketType.Unreliable)
                                    {
                                        Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.UnreliableFragment);
                                    }
                                    else
                                    {
                                        Debug.Assert(false);
                                    }
                                }
                                reassembleList.Add(channelData.receiveQueue[seq]);
                            }
                            DataPacket dataPacket = ReassembleDataPacket(reassembleList);
                            try
                            {
                                OnPacketReceived?.Invoke(dataPacket);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                            }
                            channelData.remoteSeq = (ushort)(firstPacket.seq + firstPacket.fragment + 1);
                        }

                        if ((packet.packetType == PacketType.Reliable || packet.packetType == PacketType.ReliableFragment) && lastValidPacketSeq.HasValue)
                        {
                            using (MemoryStream ms = new MemoryStream())
                                using (BinaryWriter writer = new BinaryWriter(ms))
                                {
                                    writer.Write(channelData.receiveQueue[lastValidPacketSeq.Value].timestamp);
                                    writer.Flush();

                                    SendRawPacket(new NetworkPacket()
                                    {
                                        packetType = PacketType.ReliableACK,
                                        from       = localId,
                                        to         = remoteId,
                                        channel    = packet.channel,
                                        seq        = lastValidPacketSeq.Value,
                                        payload    = ms.ToArray()
                                    });
                                }
                        }
                        break;

                    case PacketType.ReliableACK:
                        //Console.WriteLine("ACKed channel=" + packet.channel + ", seq=" + packet.seq);
                        // TODO
                        break;
                    }
                }
                catch (SocketException)
                {
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
Пример #24
0
        public void ProcessRecvQueue()
        {
            foreach (var cdata in _sequences)
            {
                RUDPConnectionData sq = cdata.Value;

                List <RUDPPacket> PacketsToRecv = new List <RUDPPacket>();
                lock (sq.ReceivedPackets)
                    PacketsToRecv.AddRange(sq.ReceivedPackets.OrderBy(x => x.Seq));
                PacketsToRecv = PacketsToRecv.GroupBy(x => x.Seq).Select(g => g.First()).ToList();

                for (int i = 0; i < PacketsToRecv.Count; i++)
                {
                    RUDPPacket p = PacketsToRecv[i];

                    lock (sq.ReceivedPackets)
                        sq.ReceivedPackets.Remove(p);

                    if (p.Seq < sq.Remote)
                    {
                        continue;
                    }

                    if (p.Seq > sq.Remote)
                    {
                        sq.ReceivedPackets.Add(p);
                        break;
                    }

                    Debug("RECV <- {0}: {1}", p.Src, p);

                    if (p.Qty == 0)
                    {
                        sq.Remote++;

                        if (p.Type == RUDPPacketType.SYN)
                        {
                            if (IsServer)
                            {
                                Send(p.Src, RUDPPacketType.SYN, RUDPPacketFlags.ACK);
                                OnClientConnect?.Invoke(p.Src);
                            }
                            else if (p.Flags == RUDPPacketFlags.ACK)
                            {
                                State = ConnectionState.OPEN;
                                OnConnected?.Invoke(p.Src);
                            }
                            continue;
                        }

                        OnPacketReceived?.Invoke(p);
                    }
                    else
                    {
                        // Multipacket!
                        List <RUDPPacket> multiPackets = PacketsToRecv.Skip(i).Take(p.Qty).ToList();
                        if (multiPackets.Count == p.Qty)
                        {
                            Debug("MULTIPACKET {0}", p.Id);

                            byte[] buf;
                            using (MemoryStream ms = new MemoryStream())
                            {
                                using (BinaryWriter bw = new BinaryWriter(ms))
                                    foreach (RUDPPacket mp in multiPackets)
                                    {
                                        bw.Write(mp.Data);
                                        Debug("RECV MP <- {0}: {1}", p.Src, mp);
                                    }
                                buf = ms.ToArray();
                            }
                            Debug("MULTIPACKET ID {0} DATA: {1}", p.Id, Encoding.ASCII.GetString(buf));

                            OnPacketReceived?.Invoke(new RUDPPacket()
                            {
                                ACK        = p.ACK,
                                Retransmit = p.Retransmit,
                                Sent       = p.Sent,
                                Data       = buf,
                                Dst        = p.Dst,
                                Flags      = p.Flags,
                                Id         = p.Id,
                                Qty        = p.Qty,
                                Received   = p.Received,
                                Seq        = p.Seq,
                                Src        = p.Src,
                                Type       = p.Type
                            });

                            sq.Remote += p.Qty;
                            i         += p.Qty;
                        }
                        else
                        {
                            if (multiPackets.Count < p.Qty)
                            {
                                sq.ReceivedPackets.Add(p);
                                break;
                            }
                            else
                            {
                                Debug("P.QTY > MULTIPACKETS.COUNT ({0} > {1})", p.Qty, multiPackets.Count);
                                throw new Exception();
                            }
                        }
                    }
                }
            }
        }
Пример #25
0
        /// <summary>
        /// Handler for end of the begin receive call.
        /// </summary>
        /// <param name="ar">Contains the results of the receive.</param>
        private void EndReceiveFrom(IAsyncResult ar)
        {
            try
            {
                // When socket is closed the object will be disposed of in the middle of a receive.
                if (!m_isClosed)
                {
                    EndPoint remoteEP  = m_addressFamily == AddressFamily.InterNetwork ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0);
                    int      bytesRead = m_udpSocket.EndReceiveFrom(ar, ref remoteEP);

                    if (bytesRead > 0)
                    {
                        // During experiments IPPacketInformation wasn't getting set on Linux. Without it the local IP address
                        // cannot be determined when a listener was bound to IPAddress.Any (or IPv6 equivalent). If the caller
                        // is relying on getting the local IP address on Linux then something may fail.
                        //if (packetInfo != null && packetInfo.Address != null)
                        //{
                        //    localEndPoint = new IPEndPoint(packetInfo.Address, localEndPoint.Port);
                        //}

                        byte[] packetBuffer = new byte[bytesRead];
                        // TODO: When .NET Frmework support is dropped switch to using a slice instead of a copy.
                        Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead);
                        OnPacketReceived?.Invoke(this, m_localEndPoint.Port, remoteEP as IPEndPoint, packetBuffer);
                    }
                }

                // If there is still data available it should be read now. This is more efficient than calling
                // BeginReceiveFrom which will incur the overheaed of creating the callback and then immediately firing it.
                // It also avoids the situation where if the application cannot keep up with the network then BeginReceiveFrom
                // will be called synchronously (if data is available it calls the callback method immediately) which can
                // create a very nasty stack.
                if (!m_isClosed && m_udpSocket.Available > 0)
                {
                    EndPoint remoteEP = m_addressFamily == AddressFamily.InterNetwork ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0);

                    while (!m_isClosed && m_udpSocket.Available > 0)
                    {
                        int bytesReadSync = m_udpSocket.ReceiveFrom(m_recvBuffer, 0, m_recvBuffer.Length, SocketFlags.None, ref remoteEP);

                        if (bytesReadSync > 0)
                        {
                            byte[] packetBufferSync = new byte[bytesReadSync];
                            // TODO: When .NET Frmework support is dropped switch to using a slice instead of a copy.
                            Buffer.BlockCopy(m_recvBuffer, 0, packetBufferSync, 0, bytesReadSync);
                            OnPacketReceived?.Invoke(this, m_localEndPoint.Port, remoteEP as IPEndPoint, packetBufferSync);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            catch (SocketException resetSockExcp) when(resetSockExcp.SocketErrorCode == SocketError.ConnectionReset)
            {
                // Thrown when close is called on a socket from this end. Safe to ignore.
            }
            catch (SocketException sockExcp)
            {
                // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during
                // normal RTP operation. For example:
                // - the RTP connection may start sending before the remote socket starts listening,
                // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old
                //   or new socket during the transition.
                // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur
                // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in
                // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP
                // error since the remote party may not have initialised their socket yet.
                logger.LogWarning($"SocketException UdpReceiver.EndReceiveFrom ({sockExcp.SocketErrorCode}). {sockExcp}");
            }
            catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored.
            { }
            catch (Exception excp)
            {
                logger.LogError($"Exception UdpReceiver.EndReceiveFrom. {excp}");
                Close(excp.Message);
            }
            finally
            {
                if (!m_isClosed)
                {
                    BeginReceiveFrom();
                }
            }
        }
Пример #26
0
        void UpdateServer()
        {
            IPEndPoint Sender = null;

            if (ReceivePacket(ref Sender, out NetPacket Packet))
            {
                NetWreckClient Cli = FindOrCreateClient(Sender);
                Packet.SetIsValid(Cli.OnPacketReceived(Timestamp(), Packet));

                if (Packet.IsValid())
                {
                    Packet.Sender = Cli;

                    switch (Cli.State)
                    {
                    case ClientState.Connecting: {
                        if (OnClientConnecting != null)
                        {
                            OnClientConnecting(Cli, Packet);
                        }
                        else
                        {
                            AcceptConnection(Cli);
                        }
                        break;
                    }

                    case ClientState.Connected: {
                        if (Packet.Type == PacketType.ConnectionRequest)
                        {
                            AcceptConnection(Cli);
                            break;
                        }

                        OnPacketReceived?.Invoke(Packet);
                        break;
                    }

                    case ClientState.Disconnected: {
                        Disconnect(Cli);
                        break;
                    }

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    DebugPrint("Dropping invalid packet 2");
                }

                FreePacket(Packet);
            }

            NetWreckClient[] Clients = ServerClientList.ToArray();
            foreach (var C in Clients)
            {
                double LastReceived = LastReceiveTime(C);

                if (LastReceived > 10000)
                {
                    ServerClientList.Remove(C);
                }
                else if (LastReceived > 2000)
                {
                    Disconnect(C);
                }
                else
                {
                    C.HandleQueuedPackets(this);
                }
            }
        }
Пример #27
0
 private void OnPacketReceivedInternal(string packet)
 {
     OnPacketReceived?.Invoke(packet);
 }
Пример #28
0
        void UpdateClient()
        {
            if (ServerConnectionClient == null)
            {
                return;
            }

            if (ReceivePacket(ref ServerConnectionClient.SenderEndPoint, out NetPacket Packet))
            {
                Packet.SetIsValid(ServerConnectionClient.OnPacketReceived(Timestamp(), Packet));

                if (Packet.IsValid())
                {
                    Packet.Sender = ServerConnectionClient;

                    switch (ServerConnectionClient.State)
                    {
                    case ClientState.Connecting:
                        if (Packet.Type == PacketType.ConnectionAccept)
                        {
                            ServerConnectionClient.State = ClientState.Connected;
                            OnClientConnected?.Invoke(ServerConnectionClient);
                            break;
                        }

                        break;

                    case ClientState.Connected:
                        if (Packet.Type == PacketType.ConnectionAccept)
                        {
                            break;
                        }

                        if (Packet.Type == PacketType.Disconnect)
                        {
                            Disconnect(ServerConnectionClient);
                            break;
                        }

                        OnPacketReceived?.Invoke(Packet);
                        break;

                    case ClientState.Disconnected:
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    DebugPrint("Dropping invalid packet 2");
                }

                FreePacket(Packet);
            }

            if (ServerConnectionClient.State == ClientState.Connecting)
            {
                // If last packet sent was more than half a second ago, try again
                if (LastSendTime(ServerConnectionClient) > 500)
                {
                    NetPacket P = AllocPacket();
                    P.PacketNum = 0;
                    P.Payload   = new byte[0];
                    P.Type      = PacketType.ConnectionRequest;
                    SendPacket(P, ServerConnectionClient);
                    FreePacket(P);
                }
            }
            else if (ServerConnectionClient.State == ClientState.Connected)
            {
                ServerConnectionClient.HandleQueuedPackets(this);
            }
        }
Пример #29
0
        private void OnDataReceived(IAsyncResult iar)
        {
            SocketInfo socketInfo = (SocketInfo)iar.AsyncState;

            try
            {
                int received = socketInfo.Socket.EndReceive(iar);
                if (received == 0)
                {
                    if (OnClientDisconnected != null)
                    {
                        OnClientDisconnected(this);
                    }
                    return;
                }

                socketInfo.Index += received;


                byte[] dataa = new byte[received];
                Buffer.BlockCopy(socketInfo.DataBuffer, 0, dataa, 0, received);
                if (OnPacketReceived != null)
                {
                    OnPacketReceived.Invoke(new PacketReader(dataa));
                }
                //Console.WriteLine(BitConverter.ToString(dataa));
                //Console.WriteLine(HexEncoding.ToStringFromAscii(dataa));
                WaitForData();

                /*if (socketInfo.Index == socketInfo.DataBuffer.Length) {
                 *      switch (socketInfo.State) {
                 *              case SocketInfo.StateEnum.Header:
                 *                      PacketReader headerReader = new PacketReader(socketInfo.DataBuffer);
                 *                      byte[] packetHeaderB = headerReader.ToArray();
                 *                      int packetHeader = headerReader.ReadInt();
                 *                      short packetLength = (short)MapleCrypto.getPacketLength(packetHeader);
                 *                      if (!_RIV.checkPacket(packetHeader)) {
                 *                              Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Packet check failed. Disconnecting client.");
                 *                              this.Socket.Close();
                 *                              }
                 *                      socketInfo.State = SocketInfo.StateEnum.Content;
                 *                      socketInfo.DataBuffer = new byte[packetLength];
                 *                      socketInfo.Index = 0;
                 *                      WaitForData(socketInfo);
                 *                      break;
                 *              case SocketInfo.StateEnum.Content:
                 *                      byte[] data = socketInfo.DataBuffer;
                 *
                 *                      _RIV.crypt(data);
                 *                      MapleCustomEncryption.Decrypt(data);
                 *
                 *                      if (data.Length != 0 && OnPacketReceived != null) {
                 *                              OnPacketReceived(new PacketReader(data));
                 *                              }
                 *                      WaitForData();
                 *                      break;
                 *              }
                 *      } else {
                 *      Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Warning] Not enough data");
                 *      WaitForData(socketInfo);
                 *      }*/
            }
            catch (ObjectDisposedException)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed");
                //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed");
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10054)
                {
                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se);
                    //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se);
                }
            }
            catch (Exception e)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e);
                //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e);
            }
        }
Пример #30
0
        private unsafe void DeviceOnPacketArrival(object sender, CaptureEventArgs e)
        {
            var fullPacket = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
            var packet     = fullPacket.Extract <TcpPacket>();

            if (!packet.Push)
            {
                return;               // Only TCP PSH has actual data; ACK does not
            }
            var ipv4Info   = fullPacket.Extract <IPv4Packet>();
            var connection = new StringBuilder(ipv4Info.SourceAddress.ToString())
                             .Append(':')
                             .Append(packet.SourcePort.ToString())
                             .Append("=>")
                             .Append(ipv4Info.DestinationAddress)
                             .Append(':')
                             .Append(packet.DestinationPort.ToString())
                             .ToString();

            // All FFXIV packets begin with a packet header...
            fixed(void *payload = &packet.PayloadData[0])
            {
                var packetHeader = Marshal.PtrToStructure <PacketHeader>(new IntPtr(payload));

                if (!IsMagical(packetHeader))
                {
                    return;
                }

                // ...possibly with a compressed payload,
                using var remainder = new UnmanagedMemoryStream(
                          (byte *)payload + 40,
                          packet.PayloadData.Length - 40,
                          packet.PayloadData.Length * 2,
                          FileAccess.ReadWrite);

                if (packetHeader.IsCompressed)
                {
                    using var deflateStream = new DeflateStream(remainder, CompressionMode.Decompress);
                    deflateStream.CopyTo(remainder);
                }

                // ...followed by one or more segment headers,
                var segmentPtr = remainder.PositionPointer;
                var segments   = new List <Segment>();

                for (var i = 0; i < packetHeader.SegmentCount; i++)
                {
                    var segmentHeader = Marshal.PtrToStructure <SegmentHeader>(new IntPtr(segmentPtr));

                    // ...potentially with an IPC header and body.
                    IpcHeader ipcHeader = null;
                    var       ipcData   = new byte[0];
                    if (segmentHeader.Type == SegmentType.Ipc)
                    {
                        ipcHeader = Marshal.PtrToStructure <IpcHeader>(new IntPtr(segmentPtr + 16));
                        ipcData   = new byte[segmentHeader.Size];
                        using var ipcDataStreamUnmanaged = new UnmanagedMemoryStream(segmentPtr + 32, segmentHeader.Size);
                        using var ipcDataStream          = new MemoryStream(ipcData, writable: true);
                        ipcDataStreamUnmanaged.CopyTo(ipcDataStream);

                        OnIpcMessageReceived?.Invoke(connection, new FFXIVIpcMessage(ipcHeader, ipcData));

                        segmentPtr += 16 + segmentHeader.Size;
                    }

                    segments.Add(new Segment(segmentHeader, ipcHeader, ipcData));
                }

                OnPacketReceived?.Invoke(connection, new FFXIVPacket(packetHeader, segments));
            }
        }