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; } }
void SendHello() { var size = new PeerToPeerHello(m_Connection.SelfId, null).Pack(m_Connection.m_SendBuffer); m_Connection.m_Socket.Send(m_Connection.m_SendBuffer, 0, size, m_RemoteEP); if (m_LocalEP != null) { m_Connection.m_Socket.Send(m_Connection.m_SendBuffer, 0, size, m_LocalEP); } }
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(); }
public void OnPeerToPeerHello(PeerToPeerHello packet, IPEndPoint remoteEP) { if (packet.CookieSize > 0) { StartHandshake(packet, remoteEP); } else { //こちらのCookieを返す var size = new PeerToPeerHello(m_Connection.SelfId, m_CookieProvider.Cookie).Pack(m_Connection.m_SendBuffer); m_Connection.m_Socket.Send(m_Connection.m_SendBuffer, 0, size, remoteEP); } }
void OnPeerToPeerHello(byte[] buf, int size, IPEndPoint remoteEP) { if (!UseP2P) { return; } if (PeerToPeerHello.TryUnpack(buf, size, out var packet)) { Log.Debug("receive p2p hello {0}", remoteEP); P2PTask.OnPeerToPeerHello(packet, remoteEP); } else { Log.Warning("unpack fail p2p hello {0}", remoteEP); } }
public static bool TryUnpack(byte[] buf, int size, out PeerToPeerHello packet) { if (size < 5 || buf[0] != (byte)Type) { packet = default; return(false); } int offset = 1; int id = BinaryUtil.ReadInt(buf, ref offset); byte cookieSize = buf[offset++]; byte[] cookie = default; if (cookieSize > 0) { cookie = BinaryUtil.ReadBytes(buf, cookieSize, ref offset); } packet = new PeerToPeerHello(id, cookie); return(true); }
async Task <PeerToPeerHello> WaitHello() { while (true) { var receive = await m_Socket.ReceiveAsync(); var buf = receive.Buffer; int size = buf.Length; if (DiscoveryHolePunch.TryUnpack(buf, size, out var _)) { continue; } if (PeerToPeerHello.TryUnpack(buf, size, out var packet)) { m_RemoteEP = receive.RemoteEndPoint; m_RemoteLocalEP = null; return(packet); } throw new Exception("fail PeerToPeerHello"); } }
void StartHandshake(PeerToPeerHello packet, IPEndPoint remoteEP) { GetTask(packet.ConnectionId)?.OnPeerToPeerHello(packet, remoteEP); }