Example #1
0
        private void Attempt_(NetworkAddress addr, DateTimeOffset nTime)
        {
            AddressInfo pinfo = Find(addr.Endpoint.Address);

            // if not found, bail out
            if (pinfo == null)
            {
                return;
            }

            AddressInfo info = pinfo;

            // check whether we are talking about the exact same CService (including same port)
            if (!info.Match(addr))
            {
                return;
            }

            // update info
            info.LastTry = nTime;
            info.nAttempts++;
        }
Example #2
0
 public AddrPayload(NetworkAddress address)
 {
     addr_list = new NetworkAddress[] { address };
 }
Example #3
0
 public AddressInfo(NetworkAddress addr, IPAddress addrSource)
 {
     Address = addr;
     Source  = addrSource;
 }
Example #4
0
 public void Good(NetworkAddress addr)
 {
     Good(addr, DateTimeOffset.UtcNow);
 }
Example #5
0
 private AddressInfo Find(NetworkAddress addr, out int nId)
 {
     return(Find(addr.Endpoint.Address, out nId));
 }
Example #6
0
        private bool Add_(NetworkAddress addr, IPAddress source, TimeSpan nTimePenalty)
        {
            if (!addr.Endpoint.Address.IsRoutable(true))
            {
                return(false);
            }

            bool        fNew = false;
            int         nId;
            AddressInfo pinfo = Find(addr, out nId);

            if (pinfo != null)
            {
                // periodically update nTime
                bool fCurrentlyOnline = (DateTimeOffset.UtcNow - addr.Time < TimeSpan.FromSeconds(24 * 60 * 60));
                var  nUpdateInterval  = TimeSpan.FromSeconds(fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
                if (addr.ntime != 0 && (pinfo.Address.ntime == 0 || pinfo.Address.Time < addr.Time - nUpdateInterval - nTimePenalty))
                {
                    pinfo.Address.ntime = (uint)Math.Max(0L, (long)Utils.DateTimeToUnixTime(addr.Time - nTimePenalty));
                }

                // add services
                pinfo.Address.Service |= addr.Service;

                // do not update if no new information is present
                if (addr.ntime == 0 || (pinfo.Address.ntime != 0 && addr.Time <= pinfo.Address.Time))
                {
                    return(false);
                }

                // do not update if the entry was already in the "tried" table
                if (pinfo.fInTried)
                {
                    return(false);
                }

                // do not update if the max reference count is reached
                if (pinfo.nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
                {
                    return(false);
                }

                // stochastic test: previous nRefCount == N: 2^N times harder to increase it
                int nFactor = 1;
                for (int n = 0; n < pinfo.nRefCount; n++)
                {
                    nFactor *= 2;
                }
                if (nFactor > 1 && (GetRandInt(nFactor) != 0))
                {
                    return(false);
                }
            }
            else
            {
                pinfo = Create(addr, source, out nId);
                pinfo.Address.ntime = (uint)Math.Max((long)0, (long)Utils.DateTimeToUnixTime(pinfo.Address.Time - nTimePenalty));
                nNew++;
                fNew = true;
            }

            int nUBucket    = pinfo.GetNewBucket(nKey, source);
            int nUBucketPos = pinfo.GetBucketPosition(nKey, true, nUBucket);

            if (vvNew[nUBucket, nUBucketPos] != nId)
            {
                bool fInsert = vvNew[nUBucket, nUBucketPos] == -1;
                if (!fInsert)
                {
                    AddressInfo infoExisting = mapInfo[vvNew[nUBucket, nUBucketPos]];
                    if (infoExisting.IsTerrible || (infoExisting.nRefCount > 1 && pinfo.nRefCount == 0))
                    {
                        // Overwrite the existing new table entry.
                        fInsert = true;
                    }
                }
                if (fInsert)
                {
                    ClearNew(nUBucket, nUBucketPos);
                    pinfo.nRefCount++;
                    vvNew[nUBucket, nUBucketPos] = nId;
                }
                else
                {
                    if (pinfo.nRefCount == 0)
                    {
                        Delete(nId);
                    }
                }
            }
            return(fNew);
        }
Example #7
0
 public bool Add(NetworkAddress addr)
 {
     return(Add(addr, IPAddress.Loopback));
 }
Example #8
0
 //! Add a single address.
 public bool Add(NetworkAddress addr, IPAddress source)
 {
     return(Add(addr, source, TimeSpan.Zero));
 }
Example #9
0
 internal bool Match(NetworkAddress addr)
 {
     return
         (Address.Endpoint.Address.Equals(addr.Endpoint.Address) &&
          Address.Endpoint.Port == addr.Endpoint.Port);
 }
Example #10
0
 //! Mark an entry as currently-connected-to.
 public void Connected(NetworkAddress addr)
 {
     Connected(addr, DateTimeOffset.UtcNow);
 }
Example #11
0
 //! Mark an entry as connection attempted to.
 public void Attempt(NetworkAddress addr)
 {
     Attempt(addr, DateTimeOffset.UtcNow);
 }
Example #12
0
        private void ProcessMessageCore(IncomingMessage message)
        {
            if (message.Message.Payload is VersionPayload)
            {
                var version         = message.AssertPayload <VersionPayload>();
                var connectedToSelf = version.Nonce == Nonce;
                if (message.Node != null && connectedToSelf)
                {
                    NodeServerTrace.ConnectionToSelfDetected();
                    message.Node.DisconnectAsync();
                    return;
                }

                if (message.Node == null)
                {
                    var remoteEndpoint = version.AddressFrom;
                    if (!remoteEndpoint.Address.IsRoutable(AllowLocalPeers))
                    {
                        //Send his own endpoint
                        remoteEndpoint = new IPEndPoint(((IPEndPoint)message.Socket.RemoteEndPoint).Address, Network.DefaultPort);
                    }

                    var peer = new NetworkAddress()
                    {
                        Endpoint = remoteEndpoint,
                        Time     = DateTimeOffset.UtcNow
                    };
                    var node = new Node(peer, Network, CreateNodeConnectionParameters(), message.Socket, version);

                    if (connectedToSelf)
                    {
                        node.SendMessage(CreateNodeConnectionParameters().CreateVersion(node.Peer.Endpoint, Network));
                        NodeServerTrace.ConnectionToSelfDetected();
                        node.Disconnect();
                        return;
                    }

                    CancellationTokenSource cancel = new CancellationTokenSource();
                    cancel.CancelAfter(TimeSpan.FromSeconds(10.0));
                    try
                    {
                        ConnectedNodes.Add(node);
                        node.StateChanged += node_StateChanged;
                        node.RespondToHandShake(cancel.Token);
                    }
                    catch (OperationCanceledException ex)
                    {
                        NodeServerTrace.Error("The remote node did not respond fast enough (10 seconds) to the handshake completion, dropping connection", ex);
                        node.DisconnectAsync();
                        throw;
                    }
                    catch (Exception)
                    {
                        node.DisconnectAsync();
                        throw;
                    }
                }
            }

            var messageReceived = MessageReceived;

            if (messageReceived != null)
            {
                messageReceived(this, message);
            }
        }