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; } }
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); } } }
public void Add(PeerEntry peer) { if (m_PeerMap.TryAdd(peer.ConnectionId, peer)) { m_PeerList.Add(peer); m_Connection.OnAdd(peer); } }
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); }
protected internal override void OnRemove(PeerEntry peer) { base.OnRemove(peer); m_PeerToPeerListDirty = true; if (DisposeOnDisconnectOwner && m_Owner != null && m_Owner.ConnectionId == peer.ConnectionId) { Dispose(); } }
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); } }
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); }
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); }
public bool TryGetValue(int id, out PeerEntry peer) { return(m_PeerMap.TryGetValue(id, out peer)); }
internal protected virtual void OnAdd(PeerEntry peer) { Log.Debug("add peer id:{0}, ip", peer.ConnectionId, peer.EndPoint); OnAddPeer?.Invoke(peer); }
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); }
internal protected virtual void OnRemove(PeerEntry peer) { Log.Debug("remove peer id:{0}, ip", peer.ConnectionId, peer.EndPoint); OnRemotePeer?.Invoke(peer); }
protected internal override void OnRemove(PeerEntry peer) { m_IdGenerator?.Remove(peer.ConnectionId); base.OnRemove(peer); }
void SendP2PList(PeerEntry peer, PeerToPeerList data) { var offset = data.Pack(m_SendBuffer, peer.Encryptor); m_Socket.Send(m_SendBuffer, 0, offset, peer.EndPoint); }
protected internal override void OnAdd(PeerEntry peer) { m_PeerToPeerListDirty = true; base.OnAdd(peer); }