public PeerStatistic(PeerAddress peerAddress) { if (peerAddress == null) { throw new ArgumentException("PeerAddress cannot be null."); } Created = Convenient.CurrentTimeMillis(); _peerId = peerAddress.PeerId; PeerAddress = peerAddress; }
/// <summary> /// Creates a peer address from a continuous byte array. This is useful if you don't know the size beforehand. /// The new offset can be accessed through the Offset property. /// </summary> /// <param name="me">The serialized array.</param> /// <param name="initialOffset">The offset where to start.</param> public PeerAddress(sbyte[] me, int initialOffset) { // get the peer ID, this is independent of the type long offset = initialOffset; // get the options int options = me[offset++] & Utils.Utils.MaskFf; IsIPv6 = (options & Net6) > 0; // TODO static methods could be used instead IsFirewalledUdp = (options & FirewallUdp) > 0; IsFirewalledTcp = (options & FirewallTcp) > 0; IsRelayed = (options & Relayed) > 0; // get the relays int relays = me[offset++] & Utils.Utils.MaskFf; // first 3 bits are the size RelaySize = (relays >> TypeBitSize) & Mask07; // last 5 bits indicate if IPv6 or IPv4 var b = (byte)(relays & Mask1F); // TODO check if works (2x) _relayType = new BitArray(b); // get the ID var tmp = new sbyte[Number160.ByteArraySize]; Array.Copy(me, offset, tmp, 0, Number160.ByteArraySize); PeerId = new Number160(tmp); offset += Number160.ByteArraySize; PeerSocketAddress = PeerSocketAddress.Create(me, IsIPv4, offset); offset = PeerSocketAddress.Offset; if (RelaySize > 0) { PeerSocketAddresses = new List <PeerSocketAddress>(RelaySize); for (int i = 0; i < RelaySize; i++) { var psa = PeerSocketAddress.Create(me, !_relayType.Get(i), offset); PeerSocketAddresses.Add(psa); offset = psa.Offset; } } else { PeerSocketAddresses = EmptyPeerSocketAddresses; } Size = offset - initialOffset; Offset = offset; _hashCode = PeerId.GetHashCode(); }
/// <summary> /// Creates a new Number320 key from given location and domain keys. /// </summary> /// <param name="locationKey">The location key.</param> /// <param name="domainKey">The domain key.</param> public Number320(Number160 locationKey, Number160 domainKey) { if (locationKey == null) { throw new SystemException("LocationKey cannot be null."); } LocationKey = locationKey; if (domainKey == null) { throw new SystemException("DomainKey cannot be null."); } DomainKey = domainKey; }
/// <summary> /// Constructor with reasonable defaults. /// </summary> /// <param name="self">The peer ID of this peer.</param> public PeerMapConfiguration(Number160 self) { Self = self; BagSizeVerified = 10; BagSizeOverflow = 10; OfflineTimeout = 60; ShutdownTimeout = 20; ExceptionTimeout = 120; OfflineCount = 3; Maintenance = new DefaultMaintenance(4, new[] { 2, 4, 8, 16, 32, 64 }); IsPeerVerification = true; PeerFilters = new List <IPeerFilter>(2); }
public static SortedSet <PeerAddress> ClosePeers(Number160 self, Number160 other, int atLeast, IList <IDictionary <Number160, PeerStatistic> > peerMap) { var set = new SortedSet <PeerAddress>(CreateComparer(other)); int classMember = ClassMember(self, other); // special treatment, as we can start iterating from 0 if (classMember == -1) { for (int j = 0; j < Number160.Bits; j++) { var tmp = peerMap[j]; if (FillSet(atLeast, set, tmp)) { return(set); } } return(set); } var tmp2 = peerMap[classMember]; if (FillSet(atLeast, set, tmp2)) { return(set); } // in this case we have to go over all the bags that are smaller bool last = false; for (int i = 0; i < classMember; i++) { tmp2 = peerMap[i]; last = FillSet(atLeast, set, tmp2); } if (last) { return(set); } // in this case we have to go over all the bags that are larger for (int i = 0; i < Number160.Bits; i++) { tmp2 = peerMap[i]; FillSet(atLeast, set, tmp2); } return(set); }
/// <summary> /// Creates a peer address from a byte buffer. /// </summary> /// <param name="buffer">The channel buffer to read from.</param> public PeerAddress(AlternativeCompositeByteBuf buffer) { long readerIndex = buffer.ReaderIndex; // get the type int options = buffer.ReadByte(); IsIPv6 = (options & Net6) > 0; IsFirewalledUdp = (options & FirewallUdp) > 0; IsFirewalledTcp = (options & FirewallTcp) > 0; IsRelayed = (options & Relayed) > 0; // get the relays int relays = buffer.ReadByte(); RelaySize = (relays >> TypeBitSize) & Mask07; var b = (byte)(relays & Mask1F); // TODO check if works (2x) _relayType = new BitArray(b); // get the ID var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); PeerId = new Number160(me); PeerSocketAddress = PeerSocketAddress.Create(buffer, IsIPv4); if (RelaySize > 0) { PeerSocketAddresses = new List <PeerSocketAddress>(RelaySize); for (int i = 0; i < RelaySize; i++) { PeerSocketAddresses.Add(PeerSocketAddress.Create(buffer, !_relayType.Get(i))); } } else { PeerSocketAddresses = EmptyPeerSocketAddresses; } Size = buffer.ReaderIndex - readerIndex; Offset = -1; // not used here _hashCode = PeerId.GetHashCode(); }
/// <summary> /// Creates a peer address if all the values are known. /// </summary> /// <param name="id">The ID of the peer.</param> /// <param name="peerSocketAddress">The peer socket address including both ports UDP and TCP.</param> /// <param name="isFirewalledTcp">Indicates if the peer is not reachable via UDP.</param> /// <param name="isFirewalledUdp">Indicates if the peer is not reachable via TCP.</param> /// <param name="isRelayed">Indicates if the peer is used as a relay.</param> /// <param name="peerSocketAddresses">The relay peers.</param> public PeerAddress(Number160 id, PeerSocketAddress peerSocketAddress, bool isFirewalledTcp, bool isFirewalledUdp, bool isRelayed, ICollection <PeerSocketAddress> peerSocketAddresses) { PeerId = id; int size = Number160.ByteArraySize; PeerSocketAddress = peerSocketAddress; _hashCode = id.GetHashCode(); IsIPv6 = peerSocketAddress.InetAddress.IsIPv6(); IsFirewalledUdp = isFirewalledUdp; IsFirewalledTcp = isFirewalledTcp; IsRelayed = isRelayed; // header + TCP port + UDP port size += HeaderSize + PortsSize + (IsIPv6 ? Utils.Utils.IPv6Bytes : Utils.Utils.IPv4Bytes); if (PeerSocketAddresses == null) { PeerSocketAddresses = EmptyPeerSocketAddresses; _relayType = EmptyRelayType; RelaySize = 0; } else { RelaySize = PeerSocketAddresses.Count; if (RelaySize > TypeBitSize) { throw new ArgumentException(String.Format("Can only store up to {0} relay peers. Tried to store {1} relay peers.", TypeBitSize, RelaySize)); } PeerSocketAddresses = peerSocketAddresses; _relayType = new BitArray(RelaySize); } int index = 0; foreach (var psa in peerSocketAddresses) { bool isIPv6 = psa.InetAddress.IsIPv6(); _relayType.Set(index, isIPv6); size += psa.Size(); index++; } Size = size; Offset = -1; // not used here }
/// <summary> /// Creates a new Number640 key from given location, domain, content and version keys. /// </summary> /// <param name="locationKey">The location key.</param> /// <param name="domainKey">The domain key.</param> /// <param name="contentKey">The content key.</param> /// <param name="versionKey">The version key.</param> public Number640(Number160 locationKey, Number160 domainKey, Number160 contentKey, Number160 versionKey) { if (locationKey == null) { throw new SystemException("LocationKey cannot be null."); } LocationKey = locationKey; if (domainKey == null) { throw new SystemException("DomainKey cannot be null."); } DomainKey = domainKey; if (contentKey == null) { throw new SystemException("ContentKey cannot be null."); } ContentKey = contentKey; if (versionKey == null) // TODO check if necessary { throw new SystemException("VersionKey cannot be null."); } VersionKey = versionKey; }
public bool Reject(PeerAddress peerAddress, ICollection <PeerAddress> all, Number160 target) { if (peerAddress.InetAddress.IsIPv4()) { var ipv4 = IPv4.FromInetAddress(peerAddress.InetAddress); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var paddr in all) { if (paddr.InetAddress.IsIPv4()) { var ipv4Test = IPv4.FromInetAddress(paddr.InetAddress); if (ipv4.MaskWithNetworkMask(_mask4).Equals(ipv4Test.MaskWithNetworkMask(_mask4))) { return(true); } } } } else { var ipv6 = IPv6.FromInetAddress(peerAddress.InetAddress); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var paddr in all) { if (paddr.InetAddress.IsIPv6()) { var ipv6Test = IPv6.FromInetAddress(paddr.InetAddress); if (ipv6.MaskWithNetworkMask(_mask6).Equals(ipv6Test.MaskWithNetworkMask(_mask6))) { return(true); } } } } return(false); }
/// <summary> /// If you only need to know the ID. /// </summary> /// <param name="id">The ID of the peer.</param> public PeerAddress(Number160 id) : this(id, (IPAddress)null, -1, -1) { }
public bool Reject(PeerAddress peerAddress, ICollection <PeerAddress> all, Number160 target) { // TODO in Java: to be implemented return(false); }
/// <summary> /// Returns -1 if the first remote node is closer to the key. /// If the second node is closer, then 1 is returned. /// If both are equal, 0 is returned. /// </summary> /// <param name="id">The ID as a distance reference.</param> /// <param name="rn">The peer to test if closer to the ID.</param> /// <param name="rn2">The other peer to test if closer to the ID.</param> /// <returns>-1 if the first peer is closer, 1 otherwise. 0 if both are equal.</returns> public static int IsKadCloser(Number160 id, PeerAddress rn, PeerAddress rn2) { return(Distance(id, rn.PeerId).CompareTo(Distance(id, rn2.PeerId))); }
/// <summary> /// Creates a Kademlia distance comparer. /// </summary> /// <param name="id">The ID of this peer.</param> public KademliaComparer(Number160 id) { _id = id; }
/// <summary> /// Returns the difference in terms of bit counts of two IDs, minus 1. /// So two IDs with one bit difference are in the class 0. /// </summary> /// <param name="id1">The first ID.</param> /// <param name="id2">The second ID.</param> /// <returns>The bit difference and -1 if they are equal.</returns> internal static int ClassMember(Number160 id1, Number160 id2) { return(Distance(id1, id2).BitLength - 1); }
/// <summary> /// The distance metric is the XOR metric. /// </summary> /// <param name="id1">The first ID.</param> /// <param name="id2">The second ID.</param> /// <returns>The XOR distance.</returns> internal static Number160 Distance(Number160 id1, Number160 id2) { return(id1.Xor(id2)); }
/// <summary> /// Creates the Kademlia distance comparer. /// </summary> /// <param name="id">The ID of this peer.</param> /// <returns>The XOR comparer.</returns> public static IComparer <PeerAddress> CreateComparer(Number160 id) { return(new KademliaComparer(id)); }
/// <summary> /// Returns the number of the class that this ID belongs to. /// </summary> /// <param name="remoteId">The ID to test.</param> /// <returns>The number of bits used in the difference.</returns> private int ClassMember(Number160 remoteId) { return(ClassMember(Self, remoteId)); }
/// <summary> /// Creates a new Number640 key from given location, domain, content and version keys. /// </summary> /// <param name="key"></param> /// <param name="contentKey"></param> /// <param name="versionKey"></param> public Number640(Number320 key, Number160 contentKey, Number160 versionKey) : this(key.LocationKey, key.DomainKey, contentKey, versionKey) { }
/// <summary> /// If you only need to know the ID and the internet address. /// </summary> /// <param name="id">The ID of the peer.</param> /// <param name="inetAddress">The internet address of the peer.</param> public PeerAddress(Number160 id, IPAddress inetAddress) : this(id, inetAddress, -1, -1) { }
/// <summary> /// Create a new peer address and change the peer ID. /// </summary> /// <param name="peerId">The new peer ID.</param> /// <returns>The newly created peer address.</returns> public PeerAddress ChangePeerId(Number160 peerId) { return(new PeerAddress(peerId, PeerSocketAddress, IsFirewalledTcp, IsFirewalledUdp, IsRelayed, PeerSocketAddresses)); }
/// <summary> /// Facade for PeerAddress(Number160, IPAddress, int, int). /// </summary> /// <param name="peerId">The ID of the peer.</param> /// <param name="inetSocketAddress">The socket address of the peer. Both TCP and UDP will be set to the same port.</param> public PeerAddress(Number160 peerId, IPEndPoint inetSocketAddress) : this(peerId, inetSocketAddress.Address, inetSocketAddress.Port, inetSocketAddress.Port) { }
/// <summary> /// Facade for PeerAddress(Number160, IPAddress, int, int). /// </summary> /// <param name="peerId">The ID of the peer.</param> /// <param name="inetAddress">The internet address of the peer.</param> /// <param name="tcpPort">The TCP port of the peer.</param> /// <param name="udpPort">The UDP port of the peer.</param> public PeerAddress(Number160 peerId, string inetAddress, int tcpPort, int udpPort) : this(peerId, IPAddress.Parse(inetAddress), tcpPort, udpPort) { }
/// <summary> /// Facade for PeerAddress(Number160, PeerSocketAddress, bool, bool, bool, Collection-PeerSocketAddress>. /// </summary> /// <param name="peerId">The ID of the peer.</param> /// <param name="inetAddress">The internet address of the peer.</param> /// <param name="tcpPort">The TCP port of the peer.</param> /// <param name="udpPort">The UDP port of the peer.</param> /// <param name="options">The options for the created <see cref="PeerAddress"/>.</param> public PeerAddress(Number160 peerId, IPAddress inetAddress, int tcpPort, int udpPort, int options) : this(peerId, new PeerSocketAddress(inetAddress, tcpPort, udpPort), ReadIsFirewalledTcp(options), ReadIsFirewalledUdp(options), ReadIsRelay(options), EmptyPeerSocketAddresses) { }
// Facade Constructors: /// <summary> /// Facade for PeerAddress(Number160, PeerSocketAddress, bool, bool, bool, Collection-PeerSocketAddress>)}. /// </summary> /// <param name="peerId">The ID of the peer.</param> /// <param name="inetAddress">The internet address of the peer.</param> /// <param name="tcpPort">The TCP port of the peer.</param> /// <param name="udpPort">The UDP port of the peer.</param> public PeerAddress(Number160 peerId, IPAddress inetAddress, int tcpPort, int udpPort) // TODO both IPv4 and IPv6 can be passed here -> fix flags : this(peerId, new PeerSocketAddress(inetAddress, tcpPort, udpPort), false, false, false, EmptyPeerSocketAddresses) { }
/// <summary> /// Returns close peers from the set to a given key. This method is thread-safe. /// You can use the returned set as it is a copy of the actual peer map and changes /// in the return set do not affect the peer map. /// </summary> /// <param name="id">The key that should be close to the keys in the map.</param> /// <param name="atLeast">The number we want to find at least.</param> /// <returns>A sorted set with close peers first in this set.</returns> public SortedSet <PeerAddress> ClosePeers(Number160 id, int atLeast) { return(ClosePeers(Self, id, atLeast, PeerMapVerified)); }
public bool Reject(PeerAddress peerAddress, ICollection <PeerAddress> all, Number160 target) { // by default, don't reject anything return(false); }