示例#1
0
        void DestroyWorstNeighbor(double?mutualValueLowLimit, DateTime timeNowUtc)
        {
            if (ConnectedNeighbors.Any(x => x.IsInTeardownState))
            {
                return;
            }

            double?worstValue = mutualValueLowLimit;
            ConnectionToNeighbor worstNeighbor = null;

            foreach (var neighbor in ConnectedNeighborsCanBeUsedForNewRequests)
            {
                var p2pConnectionValue_withNeighbor =
                    P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary,
                                                                             this.Configuration.LocalPeerRegistrationId, this.ConnectedNeighborsBusySectorIds,
                                                                             neighbor.RemoteRegistrationId, neighbor.RemoteNeighborsBusySectorIds ?? 0,
                                                                             Engine.NumberOfDimensions,
                                                                             true,
                                                                             this.AnotherNeighborToSameSectorExists(neighbor),
                                                                             neighbor.Remote_AnotherNeighborToSameSectorExists ?? false
                                                                             );
                Engine.WriteToLog_p2p_higherLevelDetail(neighbor, $"@DestroyWorstNeighbor() p2pConnectionValue_withNeighbor={p2pConnectionValue_withNeighbor} from {this} to {neighbor}", null);
                if (worstValue == null || p2pConnectionValue_withNeighbor < worstValue)
                {
                    worstValue    = p2pConnectionValue_withNeighbor;
                    worstNeighbor = neighbor;
                }
            }

            if (worstNeighbor != null)
            {
                _lastTimeDetroyedWorstNeighborUtc = timeNowUtc;

                Engine.WriteToLog_p2p_higherLevelDetail(worstNeighbor, $"destroying worst P2P connection with neighbor. neighbors count = {ConnectedNeighbors.Count}", null);
                var ping = worstNeighbor.CreatePing(false, true, 0, false);

                var pendingPingRequest = new PendingLowLevelUdpRequest("pendingPingRequest 351", worstNeighbor.RemoteEndpoint,
                                                                       PongPacket.GetScanner(worstNeighbor.LocalNeighborToken32, ping.PingRequestId32), Engine.DateTimeNowUtc,
                                                                       Engine.Configuration.UdpLowLevelRequests_ExpirationTimeoutS,
                                                                       ping.Encode(),
                                                                       Engine.Configuration.UdpLowLevelRequests_InitialRetransmissionTimeoutS,
                                                                       Engine.Configuration.UdpLowLevelRequests_RetransmissionTimeoutIncrement
                                                                       );

                _ = Engine.SendUdpRequestAsync_Retransmit(pendingPingRequest); // retransmit until PONG
                worstNeighbor.IsInTeardownState = true;
                Engine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(PingPacket.ConnectionTeardownStateDurationS), () =>
                {
                    if (!worstNeighbor.IsDisposed)
                    {
                        Engine.WriteToLog_p2p_higherLevelDetail(worstNeighbor, $"destroying worst P2P connection after teardown state timeout", null);
                        worstNeighbor.Dispose();
                    }
                }, "estroying worst P2P connection 2146");
            }
        }
示例#2
0
        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}");
            }
        }