public static LocalDrpPeerConfiguration Create(ICryptoLibrary cryptoLibrary, int?numberOfDimensions = null, byte[] ed25519privateKey = null, RegistrationId registrationId = null) { LocalDrpPeerConfiguration r; if (ed25519privateKey != null && registrationId != null) { r = new LocalDrpPeerConfiguration { LocalPeerRegistrationPrivateKey = new RegistrationPrivateKey { ed25519privateKey = ed25519privateKey }, LocalPeerRegistrationId = registrationId }; } else { RegistrationId.CreateNew(cryptoLibrary, out var newPrivateKey, out var newRegistrationId); r = new LocalDrpPeerConfiguration { LocalPeerRegistrationPrivateKey = newPrivateKey, LocalPeerRegistrationId = newRegistrationId }; } if (numberOfDimensions == 2) { r.MinDesiredNumberOfNeighbors = 5; r.SoftMaxNumberOfNeighbors = 7; r.AbsoluteMaxNumberOfNeighbors = 10; } return(r); }
public static void CreateNew(ICryptoLibrary cryptoLibrary, out RegistrationPrivateKey privateKey, out RegistrationId registrationId) { privateKey = new RegistrationPrivateKey { ed25519privateKey = cryptoLibrary.GeneratePrivateKeyEd25519() }; registrationId = new RegistrationId(cryptoLibrary.GetPublicKeyEd25519(privateKey.ed25519privateKey)); }
internal void TestDirection(Logger logger, RegistrationId destinationRegId) { if (this.Configuration.LocalPeerRegistrationId.Equals(destinationRegId) == true) { return; } var diff = RegistrationId.GetDifferenceVector(this.Configuration.LocalPeerRegistrationId, destinationRegId, CryptoLibrary, Engine.Configuration.SandboxModeOnly_NumberOfDimensions); _ = TestDirection(logger, diff); }
public static RegistrationId Decode(BinaryReader reader) { var flags = reader.ReadByte(); if ((flags & FlagsMask_MustBeZero) != 0) { throw new NotImplementedException(); } var r = new RegistrationId(reader.ReadBytes(CryptoLibraries.Ed25519PublicKeySize)); return(r); }
public static double[] GetDifferenceVector(RegistrationId from, RegistrationId to, ICryptoLibrary cryptoLibrary, int numberOfDimensions) { var fromRegIdVector = RegistrationIdDistance.GetVectorValues(cryptoLibrary, from, numberOfDimensions); var destinationRegIdVector = RegistrationIdDistance.GetVectorValues(cryptoLibrary, to, numberOfDimensions); var diff = new double[fromRegIdVector.Length]; for (int i = 0; i < diff.Length; i++) { diff[i] = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(fromRegIdVector[i], destinationRegIdVector[i]); } return(diff); }
public static double GetMutualP2pConnectionValue(ICryptoLibrary cryptoLibrary, RegistrationId registrationId1, ushort neighborsBusySectorIds1, RegistrationId registrationId2, ushort neighborsBusySectorIds2, int numberOfDimensions, bool thisConnectionAlreadyExists, bool anotherNeighborToSameSectorExists1, bool anotherNeighborToSameSectorExists2, bool allowConnectionsToSameRegistrationId) { if (registrationId1.Equals(registrationId2)) { return(allowConnectionsToSameRegistrationId ? SameRegistrationIdConnectionValue : -SameRegistrationIdConnectionValue); } double r = 0; var distance = registrationId1.GetDistanceTo(cryptoLibrary, registrationId2, numberOfDimensions).ToDouble(); r -= distance; if (thisConnectionAlreadyExists) { if (anotherNeighborToSameSectorExists1 == false) { r += EmptySectorOccupationValue; } if (anotherNeighborToSameSectorExists2 == false) { r += EmptySectorOccupationValue; } } else { var vsic = new VectorSectorIndexCalculator(numberOfDimensions); var vector1to2 = RegistrationId.GetDifferenceVectorF(registrationId1, registrationId2, cryptoLibrary, numberOfDimensions); var vector1to2SectorIndex = vsic.GetSectorIndex(vector1to2); var vector1to2IsInVacantSector = ((neighborsBusySectorIds1 >> vector1to2SectorIndex) & 0x0001) == 0; if (vector1to2IsInVacantSector) { r += EmptySectorOccupationValue; } var vector2to1 = new float[numberOfDimensions]; for (int i = 0; i < numberOfDimensions; i++) { vector2to1[i] = -vector1to2[i]; } var vector2to1SectorIndex = vsic.GetSectorIndex(vector2to1); var vector2to1IsInVacantSector = ((neighborsBusySectorIds2 >> vector2to1SectorIndex) & 0x0001) == 0; if (vector2to1IsInVacantSector) { r += EmptySectorOccupationValue; } } return(r); }
internal void TestDirection(Logger logger, RegistrationId destinationRegId) { if (this.Configuration.LocalPeerRegistrationId.Equals(destinationRegId) == true) { return; } if (this.Configuration.AbsoluteMaxNumberOfNeighbors == 1) { return; // special case: mobile device connected to home device } var diff = RegistrationId.GetDifferenceVector(this.Configuration.LocalPeerRegistrationId, destinationRegId, CryptoLibrary, Engine.Configuration.SandboxModeOnly_NumberOfDimensions); _ = TestDirection(logger, diff); }
public static float[] GetDifferenceVectorF(RegistrationId from, RegistrationId to, ICryptoLibrary cryptoLibrary, int numberOfDimensions) => GetDifferenceVector(from, to, cryptoLibrary, numberOfDimensions).Select(x => (float)x).ToArray();
public RegistrationIdDistance GetDistanceTo(ICryptoLibrary cryptoLibrary, RegistrationId another, int numberOfDimensions) => new RegistrationIdDistance(cryptoLibrary, this, another, numberOfDimensions);
public static LocalDrpPeerConfiguration Create(ICryptoLibrary cryptoLibrary, int numberOfDimensions, byte[] ed25519privateKey = null, RegistrationId registrationId = null) { var privatekey = new RegistrationPrivateKey { ed25519privateKey = ed25519privateKey ?? cryptoLibrary.GeneratePrivateKeyEd25519() }; var r = new LocalDrpPeerConfiguration { LocalPeerRegistrationPrivateKey = privatekey, LocalPeerRegistrationId = new RegistrationId(registrationId?.Ed25519publicKey ?? cryptoLibrary.GetPublicKeyEd25519(privatekey.ed25519privateKey)) }; if (numberOfDimensions == 2) { r.MinDesiredNumberOfNeighbors = 5; r.SoftMaxNumberOfNeighbors = 7; r.AbsoluteMaxNumberOfNeighbors = 10; } return(r); }
public static unsafe double[] GetVectorValues(ICryptoLibrary cryptoLibrary, RegistrationId rid, int numberOfDimensions) { var r = new double[numberOfDimensions]; if (rid.CachedEd25519publicKeySha256 == null) { rid.CachedEd25519publicKeySha256 = cryptoLibrary.GetHashSHA256(rid.Ed25519publicKey); } var rid_ed25519publicKey_sha256 = rid.CachedEd25519publicKeySha256; if (numberOfDimensions == 16) { fixed(byte *rpk1a = rid_ed25519publicKey_sha256) { ushort *rpk1aPtr = (ushort *)rpk1a; int l = rid_ed25519publicKey_sha256.Length / 2; for (int i = 0; i < l; i++, rpk1aPtr++) { r[i] = (double)(*rpk1aPtr) / UInt16.MaxValue; } } } else if (numberOfDimensions == 8) { fixed(byte *rpk1a = rid_ed25519publicKey_sha256) { uint *rpk1aPtr = (uint *)rpk1a; int l = rid_ed25519publicKey_sha256.Length / 4; for (int i = 0; i < l; i++, rpk1aPtr++) { r[i] = (double)(*rpk1aPtr) / UInt32.MaxValue; } } } else if (numberOfDimensions == 4) { fixed(byte *rpk1a = rid_ed25519publicKey_sha256) { ulong *rpk1aPtr = (ulong *)rpk1a; int l = rid_ed25519publicKey_sha256.Length / 8; for (int i = 0; i < l; i++, rpk1aPtr++) { r[i] = (double)(*rpk1aPtr) / ulong.MaxValue; } } } else if (numberOfDimensions == 2) { GetVectorValues_2(rid_ed25519publicKey_sha256, out var v0, out var v1); r[0] = v0; r[1] = v1; } else { throw new NotImplementedException(); } return(r); }
public void BeginSendShortSingleMessage(UserCertificate requesterUserCertificate, RegistrationId responderRegistrationId, UserId responderUserId, string messageText, TimeSpan?retryOnFailureUntilThisTimeout, Action <Exception> cb) { Engine.EngineThreadQueue.Enqueue(async() => { var sw1 = Stopwatch.StartNew(); _retry: Logger logger = null; try { var sw2 = Stopwatch.StartNew(); var session = await SendInviteAsync(requesterUserCertificate, responderRegistrationId, responderUserId, SessionType.asyncShortSingleMessage, (logger2) => { logger = logger2; if (Engine.Configuration.SandboxModeOnly_EnableInsecureLogs) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"creating an invite session to send a message '{messageText}'"); } } }); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"invite session is ready to set up direct channel and send a message"); } try { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"remote peer accepted invite session in {(int)sw2.Elapsed.TotalMilliseconds}ms: {session.RemoteSessionDescription}"); } await session.SetupAEkeysAsync(); await session.SendShortSingleMessageAsync(messageText, requesterUserCertificate); } finally { session.Dispose(); } cb?.Invoke(null); } catch (Exception exc) { var tryAgain = retryOnFailureUntilThisTimeout.HasValue && sw1.Elapsed < retryOnFailureUntilThisTimeout.Value; logger?.WriteToLog_mediumPain($"sending INVITE failed (tryAgain={tryAgain}): {exc}"); logger?.WriteToLog_mediumPain_EmitListOfPeers($"sending INVITE failed (tryAgain={tryAgain}): {exc}"); if (tryAgain) { logger?.WriteToLog_higherLevelDetail($"trying again to send message: sw1={sw1.Elapsed.TotalSeconds}s < retryOnFailureUntilThisTimeout={retryOnFailureUntilThisTimeout.Value.TotalSeconds}s"); goto _retry; } cb?.Invoke(exc); } }, "BeginSendShortSingleMessage6342"); }
public bool Verify(ICryptoLibrary cryptoLibrary, Action <BinaryWriter> writeSignedFields, RegistrationId publicKey) { var signedData = new MemoryStream(); using (var writer = new BinaryWriter(signedData)) writeSignedFields(writer); if (cryptoLibrary.VerifyEd25519(signedData.ToArray(), ed25519signature, publicKey.Ed25519publicKey) == false) { return(false); } return(true); }
public static RegistrationSignature DecodeAndVerify(BinaryReader reader, ICryptoLibrary cryptoLibrary, Action <BinaryWriter> writeSignedFields, RegistrationId publicKey) { var r = Decode(reader); if (!r.Verify(cryptoLibrary, writeSignedFields, publicKey)) { throw new BadSignatureException("invalid registration signature 135"); } return(r); }
/// <summary> /// sends INVITE, autenticates users, returns Session to be used to create direct cannel /// </summary> /// <param name="responderUserId"> /// comes from local contact book /// </param> /// <param name="responderRegId"> /// comes from local contact book /// </param> /// <param name="loggerCb">may be invoked more than one time (in case of retrying)</param> public async Task <InviteSession> SendInviteAsync(UserCertificate requesterUserCertificate, RegistrationId responderRegistrationId, UserId responderUserId, SessionType sessionType, Action <Logger> loggerCb = null) { InviteSession session = null; try { var sw = Stopwatch.StartNew(); RoutedRequest routedRequest = null; int trialsCount = 0; Exception latestTriedNeighborException = null; _retry: trialsCount++; session = new InviteSession(this); var req = new InviteRequestPacket { NumberOfHopsRemaining = InviteRequestPacket.MaxNumberOfHopsRemaining, RequesterEcdhePublicKey = new EcdhPublicKey(session.LocalInviteAckEcdhePublicKey), RequesterRegistrationId = this.Configuration.LocalPeerRegistrationId, ResponderRegistrationId = responderRegistrationId, ReqTimestamp32S = Engine.Timestamp32S, }; var logger = new Logger(Engine, this, req, DrpPeerEngine.VisionChannelModuleName_inv_requesterSide); if (!Engine.RecentUniqueInviteRequests.Filter(req.GetUniqueRequestIdFields)) { if (trialsCount > 50) { throw new NonUniquePacketFieldsException($"could not find unique fields to send INVITE request"); } if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"waiting a second to generate ne wunique INVITE request"); } await Engine.EngineThreadQueue.WaitAsync(TimeSpan.FromSeconds(1), "inv_wait_1236"); goto _retry; } session.Logger = logger; loggerCb?.Invoke(logger); Engine.RecentUniquePublicEcdhKeys.AssertIsUnique(req.RequesterEcdhePublicKey.Ecdh25519PublicKey, "req.RequesterEcdhePublicKey"); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"generated unique ECDH key {req.RequesterEcdhePublicKey}"); } req.RequesterRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, req.GetSharedSignedFields, this.Configuration.LocalPeerRegistrationPrivateKey); this.TestDirection(logger, req.ResponderRegistrationId); routedRequest = new RoutedRequest(logger, null, null, null, req, null, routedRequest); // find best connected peer to send the request var destinationPeer = Engine.RouteInviteRequest(this, routedRequest); if (destinationPeer == null) { if (latestTriedNeighborException == null) { throw new NoNeighborsToSendInviteException(); } else { throw latestTriedNeighborException; } } InviteAck1Packet ack1; try { var reqUdpData = req.Encode_SetP2pFields(destinationPeer); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"sending {req} (ReqTimestamp32S={MiscProcedures.Uint32secondsToDateTime(req.ReqTimestamp32S)}), waiting for NPACK"); } var sentRequest = new SentRequest(Engine, logger, destinationPeer.RemoteEndpoint, destinationPeer, reqUdpData, req.ReqP2pSeq16, InviteAck1Packet.GetScanner(logger, req, destinationPeer)); var ack1UdpData = await sentRequest.SendRequestAsync("ack1 4146"); #region process ACK1 // NeighborHMAC and NeighborToken32 are already verified by scanner ack1 = InviteAck1Packet.Decode(ack1UdpData); Engine.RecentUniquePublicEcdhKeys.AssertIsUnique(ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey, $"ack1.ResponderEcdhePublicKey"); if (!ack1.ResponderRegistrationSignature.Verify(Engine.CryptoLibrary, w => { req.GetSharedSignedFields(w); ack1.GetSharedSignedFields(w, true); }, responderRegistrationId)) { throw new BadSignatureException("invalid REGISTER ACK1 ResponderRegistrationSignature 2349"); } if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"verified ACK1"); } session.DeriveSharedInviteAckDhSecret(Engine.CryptoLibrary, ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey); // send NPACK to ACK1 SendNeighborPeerAckResponseToAck1(ack1, destinationPeer); #endregion } catch (RequestFailedException exc2) { latestTriedNeighborException = exc2; if (trialsCount > 50) { throw; } logger.WriteToLog_higherLevelDetail($"trying again on error {exc2.Message}... alreadyTriedProxyingToDestinationPeers.Count={routedRequest.TriedNeighbors.Count}"); routedRequest.TriedNeighbors.Add(destinationPeer); goto _retry; } // decode and verify SD session.RemoteSessionDescription = InviteSessionDescription.Decrypt_Verify(Engine.CryptoLibrary, ack1.ToResponderSessionDescriptionEncrypted, req, ack1, false, session, responderUserId, Engine.DateTimeNowUtc); // sign and encode local SD session.LocalSessionDescription = new InviteSessionDescription { DirectChannelEndPoint = destinationPeer.LocalEndpoint, SessionType = sessionType, DirectChannelToken32 = session.LocalDirectChannelToken32 }; session.LocalSessionDescription.UserCertificate = requesterUserCertificate; session.LocalSessionDescription.UserCertificateSignature = UserCertificateSignature.Sign(Engine.CryptoLibrary, w => { req.GetSharedSignedFields(w); ack1.GetSharedSignedFields(w, true); session.LocalSessionDescription.WriteSignedFields(w); }, requesterUserCertificate ); #region send ack2 var ack2 = new InviteAck2Packet { RequesterRegistrationId = req.RequesterRegistrationId, ResponderRegistrationId = req.ResponderRegistrationId, ReqTimestamp32S = req.ReqTimestamp32S, ToRequesterSessionDescriptionEncrypted = session.LocalSessionDescription.Encrypt(Engine.CryptoLibrary, req, ack1, session, true) }; ack2.RequesterRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, w => { req.GetSharedSignedFields(w); ack1.GetSharedSignedFields(w, true); ack2.GetSharedSignedFields(w); }, this.Configuration.LocalPeerRegistrationPrivateKey); var ack2UdpData = ack2.Encode_SetP2pFields(destinationPeer); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"sending ACK2, waiting for NPACK"); } await destinationPeer.SendUdpRequestAsync_Retransmit_WaitForNPACK("ack2 234575672", ack2UdpData, ack2.ReqP2pSeq16, ack2.GetSignedFieldsForNeighborHMAC); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"received NPACK"); } #endregion #region wait for CFM if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"waiting for CFM"); } var cfmUdpData = await Engine.WaitForUdpResponseAsync(new PendingLowLevelUdpRequest("cfm 1235695", destinationPeer.RemoteEndpoint, InviteConfirmationPacket.GetScanner(logger, req, destinationPeer), Engine.DateTimeNowUtc, Engine.Configuration.CfmTimoutS )); if (cfmUdpData == null) { throw new DrpTimeoutException($"did not get CFM at invite requester from destination peer {destinationPeer} (timeout={Engine.Configuration.CfmTimoutS}s)"); } // NeighborHMAC and NeighborToken32 are already verified by scanner var cfm = InviteConfirmationPacket.Decode(cfmUdpData); if (!cfm.ResponderRegistrationSignature.Verify(Engine.CryptoLibrary, w => { req.GetSharedSignedFields(w); ack1.GetSharedSignedFields(w, true); ack2.GetSharedSignedFields(w); }, responderRegistrationId)) { throw new BadSignatureException("invalid REGISTER CFM ResponderRegistrationSignature 6398"); } if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"verified CFM"); } // send NPACK to CFM SendNeighborPeerAckResponseToCfm(cfm, destinationPeer); #endregion session.DeriveSharedPingPongHmacKey(req, ack1, ack2, cfm); return(session); } catch { session?.Dispose(); throw; } }
double _distance_sumSqr; // 32 bytes of reg. public key: split into 16 dimensions of 2 bytes // euclidean distance public unsafe RegistrationIdDistance(ICryptoLibrary cryptoLibrary, RegistrationId rpk1, RegistrationId rpk2, int numberOfDimensions) { if (rpk1.CachedEd25519publicKeySha256 == null) { rpk1.CachedEd25519publicKeySha256 = cryptoLibrary.GetHashSHA256(rpk1.Ed25519publicKey); } var rpk1_ed25519publicKey_sha256 = rpk1.CachedEd25519publicKeySha256; if (rpk2.CachedEd25519publicKeySha256 == null) { rpk2.CachedEd25519publicKeySha256 = cryptoLibrary.GetHashSHA256(rpk2.Ed25519publicKey); } var rpk2_ed25519publicKey_sha256 = rpk2.CachedEd25519publicKeySha256; if (rpk1_ed25519publicKey_sha256.Length != rpk2_ed25519publicKey_sha256.Length) { throw new ArgumentException(); } _distance_sumSqr = 0; if (numberOfDimensions == 16) { fixed(byte *rpk1a = rpk1_ed25519publicKey_sha256, rpk2a = rpk2_ed25519publicKey_sha256) { ushort *rpk1aPtr = (ushort *)rpk1a, rpk2aPtr = (ushort *)rpk2a; int l = rpk1_ed25519publicKey_sha256.Length / 2; for (int i = 0; i < l; i++, rpk1aPtr++, rpk2aPtr++) { var d_i = VectorComponentRoutine(*rpk1aPtr, *rpk2aPtr); _distance_sumSqr += d_i * d_i; } } } else if (numberOfDimensions == 8) { fixed(byte *rpk1a = rpk1_ed25519publicKey_sha256, rpk2a = rpk2_ed25519publicKey_sha256) { uint *rpk1aPtr = (uint *)rpk1a, rpk2aPtr = (uint *)rpk2a; int l = rpk1_ed25519publicKey_sha256.Length / 4; for (int i = 0; i < l; i++, rpk1aPtr++, rpk2aPtr++) { var d_i = VectorComponentRoutine(*rpk1aPtr, *rpk2aPtr); _distance_sumSqr += d_i * d_i; } } } else if (numberOfDimensions == 4) { fixed(byte *rpk1a = rpk1_ed25519publicKey_sha256, rpk2a = rpk2_ed25519publicKey_sha256) { ulong *rpk1aPtr = (ulong *)rpk1a, rpk2aPtr = (ulong *)rpk2a; int l = rpk1_ed25519publicKey_sha256.Length / 8; for (int i = 0; i < l; i++, rpk1aPtr++, rpk2aPtr++) { var d_i = VectorComponentRoutine(*rpk1aPtr, *rpk2aPtr); _distance_sumSqr += d_i * d_i; } } } else if (numberOfDimensions == 2) { GetVectorValues_2(rpk1_ed25519publicKey_sha256, out var v1_0, out var v1_1); GetVectorValues_2(rpk2_ed25519publicKey_sha256, out var v2_0, out var v2_1); var d_0 = VectorComponentRoutine(v1_0, v2_0); var d_1 = VectorComponentRoutine(v1_1, v2_1); _distance_sumSqr += d_0 * d_0; _distance_sumSqr += d_1 * d_1; } else { throw new NotImplementedException(); } }
void RouteRegistrationRequest_LocalDrpPeerIteration(LocalDrpPeer localDrpPeer, RoutedRequest routedRequest, ref double?maxP2pConnectionValue, ref ConnectionToNeighbor proxyToDestinationPeer, ref LocalDrpPeer acceptAt) { var req = routedRequest.RegisterReq; var connectedNeighborsForRouting = localDrpPeer.GetConnectedNeighborsForRouting(routedRequest).ToList(); var logger = routedRequest.Logger; var distancesToNeighbors = new List <RegistrationIdDistance>(); var requestedDirectionMulResults = new List <double>(); int connectedNeighborsCountThatMatchReqFilters = 0; foreach (var neighbor in connectedNeighborsForRouting) { if (req.MinimalDistanceToNeighbor != 0) { var distanceToNeighbor = req.RequesterRegistrationId.GetDistanceTo(_cryptoLibrary, neighbor.RemoteRegistrationId, NumberOfDimensions); distancesToNeighbors.Add(distanceToNeighbor); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"distanceToNeighbor={distanceToNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor} (req.min={req.MinimalDistanceToNeighbor})"); } if (distanceToNeighbor.IsLessThan(req.MinimalDistanceToNeighbor)) { // skip: this is too close than requested if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"skipping connection to {neighbor}: distance={distanceToNeighbor} is less than requested={req.MinimalDistanceToNeighbor}"); } continue; } } if (req.DirectionVectorNullable != null) { var requestedDirectionVector = req.DirectionVectorNullableD; var vectorFromThisToNeighbor = RegistrationId.GetDifferenceVector(req.RequesterRegistrationId, neighbor.RemoteRegistrationId, CryptoLibrary, Configuration.SandboxModeOnly_NumberOfDimensions); double mulResult = 0; for (int i = 0; i < requestedDirectionVector.Length; i++) { mulResult += requestedDirectionVector[i] * requestedDirectionVector[i]; } requestedDirectionMulResults.Add(mulResult); if (mulResult < 0) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"skipping connection to {neighbor}: direction from requester to neighbor does not match requested vector"); } continue; } } connectedNeighborsCountThatMatchReqFilters++; var p2pConnectionValue_withNeighbor = P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary, req.RequesterRegistrationId, req.RequesterNeighborsBusySectorIds, neighbor.RemoteRegistrationId, neighbor.RemoteNeighborsBusySectorIds ?? 0, NumberOfDimensions, false, false, false); if (logger.WriteToLog_deepDetail_enabled) { logger.WriteToLog_deepDetail($"p2pConnectionValue_withNeighbor={p2pConnectionValue_withNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor}"); } if (maxP2pConnectionValue == null || maxP2pConnectionValue < p2pConnectionValue_withNeighbor) { maxP2pConnectionValue = p2pConnectionValue_withNeighbor; proxyToDestinationPeer = neighbor; acceptAt = null; } } if (connectedNeighborsCountThatMatchReqFilters == 0 && connectedNeighborsForRouting.Count != 0) { if (req.MinimalDistanceToNeighbor != 0) { // special case: we are inside the "minDistance" hypersphere: move away from the requester, proxy to most distant neighbor if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"special case: move away from the requester, proxy to most distant neighbor"); } RegistrationIdDistance maxDistance = null; for (int i = 0; i < connectedNeighborsForRouting.Count; i++) { var neighbor = connectedNeighborsForRouting[i]; var distanceToNeighbor = distancesToNeighbors[i]; if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"distanceToConnectedPeer={distanceToNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor} (req.min={req.MinimalDistanceToNeighbor})"); } if (maxDistance == null || distanceToNeighbor.IsGreaterThan(maxDistance)) { maxDistance = distanceToNeighbor; proxyToDestinationPeer = neighbor; acceptAt = null; } } } if (req.DirectionVectorNullable != null) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"special case: move towards the specified direction"); } double?maxMulResult = null; for (int i = 0; i < connectedNeighborsForRouting.Count; i++) { var neighbor = connectedNeighborsForRouting[i]; var mulResult = requestedDirectionMulResults[i]; if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"mulResult={mulResult} for {neighbor}"); } if (maxMulResult == null || mulResult > maxMulResult) { maxMulResult = mulResult; proxyToDestinationPeer = neighbor; acceptAt = null; } } } } // dont connect to local peer if already connected if (localDrpPeer.Configuration.LocalPeerRegistrationId.Equals(req.RequesterRegistrationId) == true) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"not accepting request at local peer: it has same regID {req.RequesterRegistrationId}"); } } else if (localDrpPeer.ConnectedNeighbors.Any(x => x.RemoteRegistrationId.Equals(req.RequesterRegistrationId)) == true) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"not accepting request at local peer: already connected to {req.RequesterRegistrationId}"); } } else if (localDrpPeer.ConnectedNeighbors.Count > localDrpPeer.Configuration.AbsoluteMaxNumberOfNeighbors) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"not accepting request at local peer: already too many neighbors ({localDrpPeer.ConnectedNeighbors.Count})"); } } else { var p2pConnectionValue_withLocalPeer = P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary, req.RequesterRegistrationId, req.RequesterNeighborsBusySectorIds, localDrpPeer.Configuration.LocalPeerRegistrationId, localDrpPeer.ConnectedNeighborsBusySectorIds, NumberOfDimensions, false, false, false); if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"p2pConnectionValue_withLocalPeer={p2pConnectionValue_withLocalPeer} from REGISTER REQ {req.RequesterRegistrationId} to {localDrpPeer.Configuration.LocalPeerRegistrationId}"); } if (maxP2pConnectionValue == null || p2pConnectionValue_withLocalPeer > maxP2pConnectionValue) { maxP2pConnectionValue = p2pConnectionValue_withLocalPeer; proxyToDestinationPeer = null; acceptAt = localDrpPeer; } } if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"<< RouteRegistrationRequest_LocalDrpPeerIteration() proxyTo={proxyToDestinationPeer}, acceptAt={acceptAt}"); } }
internal bool PendingRegisterRequestExists(RegistrationId regId) => _pendingRegisterRequests.Contains(regId);
public bool PendingInviteRequestExists(RegistrationId requesterRegId) => _pendingInviteRequests.Contains(requesterRegId);