示例#1
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);
                }
            }
        }
示例#2
0
        async Task <HandshakeResult> WaitHandshakeAccept()
        {
            while (true)
            {
                var receive = await m_Socket.ReceiveAsync();

                var buf  = receive.Buffer;
                int size = buf.Length;
                if (size == 0 || buf[0] != (byte)PeerToPeerAccept.Type)
                {
                    continue;
                }
                int          offset = 5;
                int          nonce  = BinaryUtil.ReadInt(buf, ref offset);
                EncryptorKey key    = default;
                key.Cookie       = m_Cookie;
                key.MajorVersion = Protocol.MajorVersion;
                key.MinorVersion = Protocol.MinorVersion;
                key.Nonce        = nonce;
                key.ConnectionId = m_SelfId;
                key.Random       = new ArraySegment <byte>(m_Randam);

                var encryptor = m_EncryptorGenerator.Generate(in key);

                if (!PeerToPeerAccept.TryUnpack(buf, size, encryptor, out var packet))
                {
                    throw new Exception("fail unpack HandshakeAccept");
                }
                m_RemoteEP = receive.RemoteEndPoint;
                return(new HandshakeResult(encryptor, packet.GetPeerToPeerList()));
            }
        }
示例#3
0
        public async Task <ClientConnectionImpl> Run()
        {
            try
            {
                m_Socket = new UdpSocket();
                m_Socket.Bind(m_Settings.EndPoint.AddressFamily);
                if (!m_Settings.UseP2P)
                {
                    m_Socket.Connect(m_Settings.EndPoint);
                }
                byte[] cookie;
                if (m_Settings.Cookie == null)
                {
                    var buf = new ClientHello(Protocol.MajorVersion, Protocol.MinorVersion).Pack();
                    var req = new TimeoutRetryableRequester <ServerHello>(WaitServerHello(), () => Send(buf), m_Token);
                    var res = await req.Run();

                    cookie = res.Cookie;
                }
                else
                {
                    cookie = m_Settings.Cookie;
                }
                {
                    m_Token.ThrowIfCancellationRequested();

                    var    payload    = new HandshakeRequestPayload(Random.GenInt(), m_Randam);
                    byte[] payloadBuf = payload.Pack();
                    if (m_Settings.RSA != null)
                    {
                        payloadBuf = m_Settings.RSA.Encrypt(payloadBuf, RSAEncryptionPadding.Pkcs1);
                    }
                    var request = new HandshakeRequest(cookie, payloadBuf);

                    m_EncryptorKey = new EncryptorKey(request, payload, 0);

                    var res = await(new TimeoutRetryableRequester <HandshakeResult>(WaitHandshakeAccept(), () => Send(request.Pack()), m_Token)).Run();

                    m_Token.ThrowIfCancellationRequested();

                    return(new ClientConnectionImpl(res.ConnectionId, m_Socket, m_Settings, res.Encryptor, m_EncryptorGenerator));
                }
            }
            catch (Exception ex)
            {
                Log.Exception(ex);
                m_Socket.Dispose();
                m_EncryptorGenerator.Dispose();
                throw;
            }
        }
示例#4
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);
        }
示例#5
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);
 }