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; } }
public EncryptorKey(PeerToPeerRequest request, byte[] randam, int nonce) { Cookie = request.Cookie; MajorVersion = request.MajorVersion; MinorVersion = request.MinorVersion; Nonce = nonce; ConnectionId = request.ConnectionId; Random = new ArraySegment <byte>(randam); }
public void OnPeerToPeerHello(PeerToPeerHello packet, IPEndPoint remoteEP) { if (m_LocalEP != null && remoteEP.Address.Equals(m_LocalEP.Address) && remoteEP.Port == m_LocalEP.Port) { m_LocalEP = null; } m_RemoteEP = remoteEP; m_Request = new PeerToPeerRequest(m_Connection.SelfId, packet.Cookie); m_HandshakePacket = m_Request.Pack(); Send(); }
void OnPeerToPeerRequest(byte[] buf, int size, IPEndPoint remoteEP) { if (PeerToPeerRequest.TryUnpack(m_CookieProvider, buf, size, out var packet)) { Log.Debug("receive p2p request {0}", remoteEP); P2PTask.HandshakeAccept(packet, remoteEP); } else { Log.Warning("unpack fail p2p request {0}", remoteEP); } }
public static bool TryUnpack(CookieProvider cookieProvider, byte[] buf, int size, out PeerToPeerRequest packet) { if (size < CookieProvider.CookieSize + 7 || !cookieProvider.Check(buf, 7, out var cookie)) { packet = default; return(false); } int offest = 1; var id = BinaryUtil.ReadInt(buf, ref offest); byte majorVersion = buf[offest++]; byte minorVersion = buf[offest++]; packet = new PeerToPeerRequest(id, majorVersion, minorVersion, cookie); 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); }