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); } } }
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())); } }
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; } }
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); }
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); }