예제 #1
0
        public async UniTask CreateKey(byte[] buffer, UdpClient udpSocket ,SocketUdp socketUdp)
        {
            var publicKey = RSAPublicKey.Deserialize(buffer);
            RSA = new RSA();
            var key = RSA.CreateKey(publicKey.Modules, publicKey.Exponent);
            AESKey = key.aeskey;

            Command obj = new Command
            {
                P2PEventType = CommandType.AcceptKey,
                Value = key.encrypted,
            };
            var array = new Command[1];
            array[0] = obj;

            var l2 = new UdpPacketL2
            {
                Commands = array,
                PacketNumber = 0,
                ACKNumber = 0,
            }.Serialize();

            var buf = new UdpPacket
            {
                PeerID = UniP2PManager.MyPeerID,
                UdpPacketL2 = l2,
                UdpPacketL2IV = null
            }.Serialize();
            
            await udpSocket.SendAsync(buf, buf.Length, Peer.IPEndPoint);
            PacketCapture.Write(Peer.IPEndPoint.ToString(), buf.Length, "CreateKey");
            State = UdpConnectionState.Connected;
            Peer.State = PeerState.Connected;
            InitHeartBeatAsync(socketUdp);
        }
예제 #2
0
        private async UniTask SendPingResponsePacketAsync(IPEndPoint ip, int id)
        {
            try
            {
                var commands = new Command[1];
                commands[0] = new Command
                {
                    P2PEventType = CommandType.PingResponse, Value = new PingPacket {
                        PingID = id
                    }.Serialize()
                };
                var l2 = new UdpPacketL2
                {
                    ACKNumber    = 0,
                    PacketNumber = 0,
                    Commands     = commands,
                }.Serialize();

                var packet = new UdpPacket
                {
                    PeerID        = null,
                    UdpPacketL2   = l2,
                    UdpPacketL2IV = null
                }.Serialize();

                await UdpSocket.SendAsync(packet, packet.Length, ip);

                PacketCapture.Write(ip.ToString(), packet.Length, "PingResponse");
            }
            catch (ObjectDisposedException ex)
            {
                Debugger.Error(ex.Message);
                Debugger.Log("[SocketUDP] Closed");
            }
        }
예제 #3
0
        private async UniTask SendConnectAcceptEvent(UdpConnection udp)
        {
            Command command = new Command();

            command.P2PEventType = CommandType.RequestAccept;
            command.Value        = null;
            var p = new Command[1];

            p[0] = command;

            var l2 = new UdpPacketL2
            {
                PacketNumber = 0,
                ACKNumber    = 0,
                Commands     = p,
            }.Serialize();

            var packet = new UdpPacket
            {
                PeerID        = UniP2PManager.MyPeerID,
                UdpPacketL2   = l2,
                UdpPacketL2IV = null,
            }.Serialize();

            await UdpSocket.SendAsync(packet, packet.Length, udp.Peer.IPEndPoint);

            PacketCapture.Write(udp.Peer.IPEndPoint.ToString(), packet.Length, "ConnectAcceptEvent");
            Debugger.Log("[SocketUDP] SendConnectAcceptEvent: dist:" + udp.Peer.IPEndPoint.ToString());
        }
예제 #4
0
        public async UniTask RequestKey(UdpClient UdpSocket)
        {
            State = UdpConnectionState.KeyExchange;
            RSA = new RSA();
            var publickey = RSA.RequestKey();
            
            Command obj = new Command
            {
                P2PEventType = CommandType.RequestKey,
                Value = publickey.Serialize(),
            };
            var array = new Command[1];
            array[0] = obj;
            var l2 = new UdpPacketL2
            {
                Commands = array,
                PacketNumber = 0,
                ACKNumber = 0,
            }.Serialize();

            var buf = new UdpPacket
            {
                PeerID = UniP2PManager.MyPeerID,
                UdpPacketL2 = l2,
                UdpPacketL2IV = null
            }.Serialize();

            await UdpSocket.SendAsync(buf, buf.Length, Peer.IPEndPoint);
            PacketCapture.Write(Peer.IPEndPoint.ToString(),buf.Length, "RequestKey");
        }
예제 #5
0
        public async UniTask SendUnreliable(UdpClient UdpSocket)
        {
            if (UnreliableCommandBuffer.ToArray().Length != 0)
            {
                var l2 = new UdpPacketL2
                {
                    PacketNumber = 0,
                    ACKNumber = 0,
                    Commands = UnreliableCommandBuffer.ToArray()
                }.Serialize();

                var l2Encrypt = AES.Encrypt(l2, AESKey);

                var packet = new UdpPacket
                {
                    PeerID = UniP2PManager.MyPeerID,
                    UdpPacketL2 = l2Encrypt.result,
                    UdpPacketL2IV = l2Encrypt.iv,
                }.Serialize();

                await UdpSocket.SendAsync(packet, packet.Length, Peer.IPEndPoint);
                PacketCapture.Write(Peer.IPEndPoint.ToString(), packet.Length, "Unreliable");
                UnreliableCommandBuffer.Clear();
            }
        }
예제 #6
0
        public async UniTask <int> SendPingPacketAsync(IPEndPoint ip)
        {
            int ms = 0;

            try
            {
                var objs = new Command[1];
                objs[0] = new Command {
                    P2PEventType = CommandType.PingRequest, Value = new PingPacket {
                        PingID = pingid
                    }.Serialize()
                };
                var u = new UdpPacketL2
                {
                    ACKNumber    = 0,
                    PacketNumber = 0,
                    Commands     = objs
                }.Serialize();

                var packet = new UdpPacket
                {
                    PeerID        = null,
                    UdpPacketL2   = u,
                    UdpPacketL2IV = null
                }.Serialize();
                await UdpSocket.SendAsync(packet, packet.Length, ip);

                PacketCapture.Write(ip.ToString(), packet.Length, "Ping");
                var id = pingid;
                PingTemp.Add(id, false);
                pingid++;
                do
                {
                    await UniTask.Delay(1);

                    ms++;
                }while (PingTemp[id]);
                PingTemp.Remove(id);
                return(ms);
            }
            catch (ObjectDisposedException ex)
            {
                Debugger.Error(ex.Message);
                Debugger.Log("[SocketUDP] Closed");
            }

            return(-1);
        }
예제 #7
0
        public async UniTask SendReliable(UdpClient UdpSocket)
        {
            if (State == UdpConnectionState.Connected)
            {
                /*if (!isTickReliablePacket)
                 * {
                 *  isTickReliablePacket = true;
                 *  await TickReliablePacket(UdpSocket);
                 * }*/

                if (ReliableCommandBuffer.Count != 0)
                {
                    var l2 = new UdpPacketL2
                    {
                        PacketNumber = MyPacketCount,
                        ACKNumber    = 0,
                        Commands     = ReliableCommandBuffer.ToArray(),
                    }.Serialize();

                    var l2Encrypt = AES.Encrypt(l2, AESKey);

                    var packet = new UdpPacket
                    {
                        PeerID        = UniP2PManager.MyPeerID,
                        UdpPacketL2   = l2Encrypt.result,
                        UdpPacketL2IV = l2Encrypt.iv,
                    }.Serialize();

                    await UdpSocket.SendAsync(packet, packet.Length, Peer.IPEndPoint);

                    PacketCapture.Write(Peer.IPEndPoint.ToString(), packet.Length, "Reliable");
                    //SentReliableBuffer.Add(MyPacketCount, new ReliablePacketInfo { Buffer = packet, WaitTime = 0 });
                    MyPacketCount++;
                }

                /*if (SentReliableBuffer.ContainsKey(PeerWaitPacketNumber))
                 * {
                 *  await UdpSocket.SendAsync(SentReliableBuffer[PeerWaitPacketNumber].Buffer, SentReliableBuffer[PeerWaitPacketNumber].Buffer.Length, Peer.IPEndPoint);
                 *  PacketCapture.Write(Peer.IPEndPoint.ToString(), SentReliableBuffer[PeerWaitPacketNumber].Buffer.Length, "SentReliableBuffer");
                 * }*/
            }
        }
예제 #8
0
        private async UniTask SendConnectRequestEvent(IPEndPoint ip, bool isBroadcast = false, int localport = 0)
        {
            Command command = new Command();

            command.P2PEventType = CommandType.ConnectRequest;
            command.Value        = null;
            var p = new Command[1];

            p[0] = command;

            var l2 = new UdpPacketL2
            {
                PacketNumber = 0,
                ACKNumber    = 0,
                Commands     = p,
            }.Serialize();

            var packet = new UdpPacket
            {
                PeerID        = UniP2PManager.MyPeerID,
                UdpPacketL2   = l2,
                UdpPacketL2IV = null,
            }.Serialize();

            if (isBroadcast && localport != 0)
            {
                UdpSocket.EnableBroadcast = true;
                await UdpSocket.SendAsync(packet, packet.Length, new IPEndPoint(IPAddress.Broadcast, localport));

                PacketCapture.Write("Broadcast:" + localport, packet.Length, "ConnectRequestEvent");
                UdpSocket.EnableBroadcast = false;
                await UdpSocket.SendAsync(packet, packet.Length, new IPEndPoint(UniP2PManager.PrivateIPEndPoint.Address, localport));

                PacketCapture.Write(UniP2PManager.PrivateIPEndPoint.Address.ToString() + ":" + localport, packet.Length, "ConnectRequestEvent");
            }
            else
            {
                await UdpSocket.SendAsync(packet, packet.Length, ip);
            }
        }
예제 #9
0
        private async UniTask OnReceiveCompletedAsync(byte[] buffer, IPEndPoint remote)
        {
            if (Equals(remote, UniP2PManager.PrivateIPEndPoint) || Equals(remote, UniP2PManager.StunIPEndPoint))
            {
                Debugger.Warning("[UniP2PManager] IPEndPoint is MySelf.");
                return;
            }
            UdpPacket packet = null;

            try
            {
                packet = UdpPacket.Deserialize(buffer);
            }
            catch (Exception ex)
            {
                //Debugger.Warning(ex.Message + remote.ToString());
                return;
            }

            if (packet.PeerID != null)
            {
                var udp = GetUdpConnection(packet.PeerID);

                if (udp != null)
                {
                    if (udp.State == UdpConnectionState.Connected)
                    {
                        if (packet.isEncrypt())
                        {
                            var decrypt = AES.Decrypt(packet.UdpPacketL2, udp.AESKey, packet.UdpPacketL2IV);
                            var l2      = UdpPacketL2.Deserialize(decrypt);

                            if (l2.ACKNumber != 0)
                            {
                                udp.ReceiveACKPacket(l2.ACKNumber);
                            }

                            //Reliable
                            if (l2.PacketNumber != 0)
                            {
                                //Reply ACK
                            }

                            foreach (var command in l2.Commands)
                            {
                                if (command.P2PEventType == CommandType.Disconnect)
                                {
                                    Debugger.Log("[SocketUDP] DisConnect PeerID:" + udp.Peer.ID);
                                    udp.DisConnect();
                                    UdpConnections.Remove(udp);
                                    UniP2PManager.RemovePeer(udp.Peer);
                                    return;
                                }
                                else if (command.P2PEventType == CommandType.HeartBeat)
                                {
                                    udp.ReceiveHeartBeat();
                                }
                                else if (command.P2PEventType == CommandType.Nothing || command.P2PEventType == CommandType.DataEvent)
                                {
                                    var e = new P2PEventArgs(udp.Peer, command.P2PEventType, command.Value);
                                    ReceiveSubject.OnNext(e);
                                }
                            }
                        }
                        else
                        {
                            var l2 = UdpPacketL2.Deserialize(packet.UdpPacketL2);
                            foreach (var command in l2.Commands)
                            {
                                if (command.P2PEventType == CommandType.HeartBeat)
                                {
                                    udp.ReceiveHeartBeat();
                                }
                            }
                        }
                    }
                    else if (udp.State == UdpConnectionState.KeyExchange)
                    {
                        var l2 = UdpPacketL2.Deserialize(packet.UdpPacketL2);
                        foreach (var command in l2.Commands)
                        {
                            if (command.P2PEventType == CommandType.RequestKey)
                            {
                                await udp.CreateKey(command.Value, UdpSocket, this);

                                break;
                            }
                            else if (command.P2PEventType == CommandType.AcceptKey)
                            {
                                udp.AcceptKey(command.Value, this);
                                break;
                            }
                        }
                    }

                    else if (udp.State == UdpConnectionState.RequestSend)
                    {
                        var l2 = UdpPacketL2.Deserialize(packet.UdpPacketL2);
                        foreach (var command in l2.Commands)
                        {
                            if (command.P2PEventType == CommandType.RequestAccept)
                            {
                                await ReceiveConnectAcceptEvent(udp, remote);

                                break;
                            }
                        }
                    }
                    else if (udp.State == UdpConnectionState.DisConnect)
                    {
                        udp.DisConnect();
                        return;
                    }
                }
                else
                {
                    //Not Found Udp Connection
                    var l2 = UdpPacketL2.Deserialize(packet.UdpPacketL2);

                    foreach (var command in l2.Commands)
                    {
                        if (command.P2PEventType == CommandType.ConnectRequest)
                        {
                            var peer = new Peer
                            {
                                ID         = packet.PeerID,
                                IPEndPoint = remote,
                            };
                            await ReceiveConnectRequestEvent(peer);
                        }
                        else if (command.P2PEventType == CommandType.PingRequest)
                        {
                            await SendPingResponsePacketAsync(remote, PingPacket.Deserialize(command.Value).PingID);
                        }
                        else if (command.P2PEventType == CommandType.PingResponse)
                        {
                            ReceivePingResponsePacketAsync(PingPacket.Deserialize(command.Value).PingID);
                        }
                    }
                }
            }
            else
            {
                var l2 = UdpPacketL2.Deserialize(packet.UdpPacketL2);

                foreach (var command in l2.Commands)
                {
                    if (command.P2PEventType == CommandType.PingRequest)
                    {
                        await SendPingResponsePacketAsync(remote, PingPacket.Deserialize(command.Value).PingID);
                    }
                    else if (command.P2PEventType == CommandType.PingResponse)
                    {
                        ReceivePingResponsePacketAsync(PingPacket.Deserialize(command.Value).PingID);
                    }
                }
            }
        }