예제 #1
0
        /// <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();
        }
예제 #2
0
        /// <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();
        }
예제 #3
0
        /// <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
        }
예제 #4
0
        /// <summary>
        /// Serializes to an existing array.
        /// </summary>
        /// <param name="me">The array where the result should be stored.</param>
        /// <param name="offset">The offset where to start to save the result in the byte array.</param>
        /// <returns>The new offset.</returns>
        public int ToByteArray(sbyte[] me, int offset)
        {
            // save the peer ID
            int newOffset = offset;

            me[newOffset++] = Options;
            me[newOffset++] = Relays;
            newOffset       = PeerId.ToByteArray(me, newOffset);

            // we store both the addresses of the peer and the relays
            // currently, this is not needed as we don't consider asymmetric relays
            newOffset = PeerSocketAddress.ToByteArray(me, newOffset);

            foreach (var psa in PeerSocketAddresses)
            {
                newOffset = psa.ToByteArray(me, newOffset);
            }

            return(newOffset);
        }
예제 #5
0
 public PeerAddress ChangePeerSocketAddress(PeerSocketAddress peerSocketAddress)
 {
     return(new PeerAddress(PeerId, peerSocketAddress, IsFirewalledTcp, IsFirewalledUdp, IsRelayed, PeerSocketAddresses));
 }