public override byte PerformHandshake(byte[] tag, H2NBinaryWriter response, IPEndPoint address, byte[] peerIdWanted) { var peerIdWantedStr = peerIdWanted.BytesToString(); var sessionWanted = Sessions.Values.SingleOrDefault(x => x.Peer.IdStr == peerIdWantedStr); if (_pCirrus != null) { var session = Sessions.Values.SingleOrDefault(x => x.Peer.Address.Equals(address)); if (session == null) { FATAL("UDP Hole punching error : middle equivalence not found for session wanted"); return(0); } var request = (session as Middle).Handshaker; request.Write((byte)0x22); request.Write((byte)0x21); request.Write((byte)0x0F); request.Write(sessionWanted == null ? peerIdWanted : (session as Middle).Peer.Id, 0, 0x20); request.Write(tag); return(0); } if (sessionWanted == null) { Debug("UDP Hole punching : session {0} wanted not found", peerIdWantedStr); var addresses = new List <IPEndPoint>(); if (addresses.Count == 0) { return(0); } var first = true; foreach (var _address in addresses) { response.WriteAddress(_address, first); first = false; } return(0x71); } if (sessionWanted.Failed()) { Debug("UDP Hole punching : session wanted is deleting"); return(0); } byte result = 0x00; if (_middle) { if (sessionWanted.Target != null) { var attempt = HandShakeSession.GetHelloAttempt <HelloAttempt>(tag.BytesToString()); attempt.Target = sessionWanted.Target; HandShakeSession.CreateCookie(response, attempt, tag, ""); response.Write(sessionWanted.Target.PublicKey); result = 0x70; } else { FATAL("Peer/peer dumped exchange impossible : no corresponding 'Target' with the session wanted"); } } if (result == 0x00) { /// Udp hole punching normal process var times = sessionWanted.GetHelloAttempt <Attempt>(tag.BytesToString()).Count; sessionWanted.P2PHandshake(address, tag, times, (times > 0 || address.Address.Equals(sessionWanted.Peer.Address.Address)) ? Sessions.Values.SingleOrDefault(x => x.Peer.Address.Equals(address)) : null); var first = true; foreach (var ipEndPoint in sessionWanted.Peer.Addresses) { if (ipEndPoint.Equals(address)) { WARN("A client tries to connect to himself (same {0} address)", address); } response.WriteAddress(ipEndPoint, first); Debug("P2P address initiator exchange, {0}:{1}", ipEndPoint.Address, ipEndPoint.Port); first = false; } result = 0x71; } return(result); }