void Connected_(NetworkAddress addr, DateTimeOffset nTime) { int unused; AddressInfo pinfo = Find(addr, out unused); // 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 var nUpdateInterval = TimeSpan.FromSeconds(20 * 60); if(nTime - info.nTime > nUpdateInterval) info.nTime = nTime; }
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); } }
public AddrPayload(NetworkAddress address) { addr_list = new NetworkAddress[] { address }; }
public bool Add(NetworkAddress addr) { return Add(addr, IPAddress.Loopback); }
public AddressInfo(NetworkAddress addr, IPAddress addrSource) { Address = addr; Source = addrSource; }
//! Add a single address. public bool Add(NetworkAddress addr, IPAddress source) { return Add(addr, source, TimeSpan.Zero); }
private AddressInfo Find(NetworkAddress addr, out int nId) { return Find(addr.Endpoint.Address, out nId); }
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; }
public void Good(NetworkAddress addr) { Good(addr, DateTimeOffset.UtcNow); }
//! Mark an entry as currently-connected-to. public void Connected(NetworkAddress addr) { Connected(addr, DateTimeOffset.UtcNow); }
//! Mark an entry as connection attempted to. public void Attempt(NetworkAddress addr) { Attempt(addr, DateTimeOffset.UtcNow); }
internal bool Match(NetworkAddress addr) { return Address.Endpoint.Address.Equals(addr.Endpoint.Address) && Address.Endpoint.Port == addr.Endpoint.Port; }