Ejemplo n.º 1
0
        public async Task <P2PConnectionImpl> Run()
        {
            try
            {
                m_Socket = new UdpSocket();
                m_Socket.Bind(m_RemoteEP.AddressFamily);
                m_SelfId = Random.GenInt();
                if (m_Cookie == null)
                {
                    var buf = new PeerToPeerHello(m_SelfId, null).Pack();
                    var res = await new TimeoutRetryableRequester <PeerToPeerHello>(WaitHello(), () => Send(buf), m_Token).Run();
                    m_OwnerId = res.ConnectionId;
                    m_Cookie  = res.Cookie;
                }
                {
                    var buf  = new PeerToPeerRequest(m_SelfId, m_Cookie).Pack();
                    var res  = await new TimeoutRetryableRequester <HandshakeResult>(WaitHandshakeAccept(), () => Send(buf), m_Token).Run();
                    var peer = new PeerEntry(m_OwnerId, 0, res.Encryptor, m_RemoteEP);

                    m_Token.ThrowIfCancellationRequested();
                    var impl = new P2PConnectionImpl(m_SelfId, m_Socket, peer, m_EncryptorGenerator);
                    impl.P2PTask.UpdateList(res.List.Peers, true);
                    return(impl);
                }
            }
            catch (Exception)
            {
                m_Socket.Dispose();
                throw;
            }
        }
Ejemplo n.º 2
0
        protected override void OnHandshakeRequest(byte[] buf, int size, IPEndPoint remoteEP)
        {
            if (HandshakeRequest.TryUnpack(m_CookieProvider, m_RSA, buf, size, out var packet))
            {
                int       offest   = 0;
                int       clientId = BinaryUtil.ReadInt(packet.Payload, ref offest);
                PeerEntry peer     = null;
                if (m_ClientIdPeerMap.TryGetValue(clientId, out int connectionId))
                {
                    m_PeerManager.TryGetValue(connectionId, out peer);
                }
                else if (HandshakeRequestPayload.TryUnpack(packet.Payload, out var payload))
                {
                    if (m_ClientIdBuffer.Count == ClientIdCapacity)
                    {
                        m_ClientIdPeerMap.Remove(m_ClientIdBuffer.Dequeue());
                    }
                    m_ClientIdBuffer.Enqueue(clientId);
                    var id = m_IdGenerator.Gen();
                    m_ClientIdPeerMap[clientId] = id;

                    var key       = new EncryptorKey(packet, payload, id);
                    var encryptor = m_EncryptorGenerator.Generate(in key);
                    peer = new PeerEntry(id, clientId, encryptor, remoteEP);

                    m_PeerManager.Add(peer);
                }
                if (peer != null)
                {
                    size = new HandshakeAccept(peer.ConnectionId).Pack(m_SendBuffer, peer.Encryptor);
                    m_Socket.Send(m_SendBuffer, 0, size, peer.EndPoint);
                }
            }
        }
Ejemplo n.º 3
0
 public void Add(PeerEntry peer)
 {
     if (m_PeerMap.TryAdd(peer.ConnectionId, peer))
     {
         m_PeerList.Add(peer);
         m_Connection.OnAdd(peer);
     }
 }
Ejemplo n.º 4
0
 internal P2PConnectionImpl(int selfId, UdpSocket socket, PeerEntry owner, EncryptorGenerator encryptorGenerator) : base(socket, encryptorGenerator)
 {
     SelfId = selfId;
     m_CookieProvider.Update();
     m_Owner   = owner;
     m_IsOwner = false;
     m_PeerManager.Add(m_Owner);
 }
Ejemplo n.º 5
0
 protected internal override void OnRemove(PeerEntry peer)
 {
     base.OnRemove(peer);
     m_PeerToPeerListDirty = true;
     if (DisposeOnDisconnectOwner && m_Owner != null && m_Owner.ConnectionId == peer.ConnectionId)
     {
         Dispose();
     }
 }
Ejemplo n.º 6
0
        public void HandshakeComplete(byte[] buf, int size, IPEndPoint remoteEP)
        {
            int       offset       = 1;
            int       connectionId = BinaryUtil.ReadInt(buf, ref offset);
            PeerEntry peer         = null;

            if (GetTask(connectionId)?.OnHandshakeAccept(buf, size, out peer, remoteEP) ?? false)
            {
                m_PeerManager.Add(peer);
                RemoveTask(connectionId);
            }
        }
Ejemplo n.º 7
0
        void SendImpl(PeerEntry peer, byte[] buf, int offset, int size, bool encrypt)
        {
            Log.Trace("Send id:{0}, size:{1}, encrypt:{2}", peer.ConnectionId, size, encrypt);
            int packetSize;
            int id = GetSendId(peer.ConnectionId);

            if (encrypt)
            {
                var msg = new EncryptMessage(id, peer, new ArraySegment <byte>(buf, offset, size));
                packetSize = msg.Pack(m_SendBuffer, peer.Encryptor);
            }
            else
            {
                var msg = new PlainMessage(id, peer, new ArraySegment <byte>(buf, offset, size));
                packetSize = msg.Pack(m_SendBuffer);
            }
            m_Socket.Send(m_SendBuffer, 0, packetSize, peer.EndPoint);
        }
Ejemplo n.º 8
0
        public bool OnHandshakeAccept(byte[] buf, int size, out PeerEntry peer, IPEndPoint remoteEP)
        {
            if (size < 9)
            {
                peer = null;
                return(false);
            }
            int offset    = 5;
            int nonce     = BinaryUtil.ReadInt(buf, ref offset);
            var key       = new EncryptorKey(m_Request, m_Info.Randam, nonce);
            var encryptor = m_Connection.m_EncryptorGenerator.Generate(key);

            if (!PeerToPeerAccept.TryUnpack(buf, size, encryptor, out var packet))
            {
                peer = null;
                return(false);
            }

            peer = new PeerEntry(packet.ConnectionId, nonce, encryptor, remoteEP);
            return(true);
        }
Ejemplo n.º 9
0
 public void HandshakeAccept(PeerToPeerRequest packet, IPEndPoint remoteEP)
 {
     if (!m_PeerManager.TryGetValue(packet.ConnectionId, out var peer))
     {
         int nonce     = Random.GenInt();
         var randamKey = m_RandamKey ?? GetPeerRandamKey(packet.ConnectionId);
         var key       = new EncryptorKey(packet, randamKey, nonce);
         var encryptor = m_EncryptorGenerator.Generate(in key);
         peer = new PeerEntry(packet.ConnectionId, nonce, encryptor, remoteEP);
         m_PeerManager.Add(peer);
         m_Connection.SendPeerToPeerList();
     }
     if (m_Connection.TryGetPeerToPeerList(out var list))
     {
         var size = new PeerToPeerAccept(m_Connection.SelfId, peer.ClientConnectionId, list).Pack(m_Connection.m_SendBuffer, peer.Encryptor);
         m_Connection.m_Socket.Send(m_Connection.m_SendBuffer, 0, size, remoteEP);
     }
     else
     {
         var size = new PeerToPeerAccept(m_Connection.SelfId, peer.ClientConnectionId).Pack(m_Connection.m_SendBuffer, peer.Encryptor);
         m_Connection.m_Socket.Send(m_Connection.m_SendBuffer, 0, size, remoteEP);
     }
     RemoveTask(packet.ConnectionId);
 }
Ejemplo n.º 10
0
 public bool TryGetValue(int id, out PeerEntry peer)
 {
     return(m_PeerMap.TryGetValue(id, out peer));
 }
Ejemplo n.º 11
0
 internal protected virtual void OnAdd(PeerEntry peer)
 {
     Log.Debug("add peer id:{0}, ip", peer.ConnectionId, peer.EndPoint);
     OnAddPeer?.Invoke(peer);
 }
Ejemplo n.º 12
0
        void SendPingImpl(PeerEntry peer)
        {
            var offset = new Ping(GetSendId(peer.ConnectionId), peer).Pack(m_SendBuffer, peer.Encryptor);

            m_Socket.Send(m_SendBuffer, 0, offset, peer.EndPoint);
        }
Ejemplo n.º 13
0
 internal protected virtual void OnRemove(PeerEntry peer)
 {
     Log.Debug("remove peer id:{0}, ip", peer.ConnectionId, peer.EndPoint);
     OnRemotePeer?.Invoke(peer);
 }
Ejemplo n.º 14
0
 protected internal override void OnRemove(PeerEntry peer)
 {
     m_IdGenerator?.Remove(peer.ConnectionId);
     base.OnRemove(peer);
 }
Ejemplo n.º 15
0
        void SendP2PList(PeerEntry peer, PeerToPeerList data)
        {
            var offset = data.Pack(m_SendBuffer, peer.Encryptor);

            m_Socket.Send(m_SendBuffer, 0, offset, peer.EndPoint);
        }
Ejemplo n.º 16
0
 protected internal override void OnAdd(PeerEntry peer)
 {
     m_PeerToPeerListDirty = true;
     base.OnAdd(peer);
 }