Пример #1
0
        /// <summary>
        /// Creates the peer address based on the network discovery that was done./>
        /// </summary>
        /// <param name="peerId">The ID of this peer.</param>
        /// <param name="channelClientConfiguration"></param>
        /// <param name="channelServerConfiguration"></param>
        /// <returns>The peer address of this peer.</returns>
        private static PeerAddress FindPeerAddress(Number160 peerId,
                                                   ChannelClientConfiguration channelClientConfiguration, ChannelServerConfiguration channelServerConfiguration)
        {
            string status = DiscoverNetworks.DiscoverInterfaces(channelClientConfiguration.BindingsOutgoing);

            Logger.Info("Status of external address search: " + status);

            IPAddress outsideAddress = channelClientConfiguration.BindingsOutgoing.FoundAddress;

            if (outsideAddress == null)
            {
                throw new IOException("Not listening to anything. Maybe the binding information is wrong.");
            }

            var peerSocketAddress = new PeerSocketAddress(outsideAddress,
                                                          channelServerConfiguration.Ports.TcpPort,
                                                          channelServerConfiguration.Ports.UdpPort);

            var self = new PeerAddress(peerId, peerSocketAddress,
                                       channelServerConfiguration.IsBehindFirewall,
                                       channelServerConfiguration.IsBehindFirewall,
                                       false, PeerAddress.EmptyPeerSocketAddresses);

            return(self);
        }
Пример #2
0
 public static PeerAddress CreateAddress(Number160 idSender, String inetSender, int tcpPortSender,
     int udpPortSender, bool firewallUdp, bool firewallTcp)
 {
     IPAddress inetSend = IPAddress.Parse(inetSender); // TODO correct port
     var peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
     var n1 = new PeerAddress(idSender, peerSocketAddress, firewallTcp, firewallUdp, false, PeerAddress.EmptyPeerSocketAddresses);
     return n1;
 }
Пример #3
0
        public static PeerAddress CreateAddress(Number160 idSender, String inetSender, int tcpPortSender,
                                                int udpPortSender, bool firewallUdp, bool firewallTcp)
        {
            IPAddress inetSend          = IPAddress.Parse(inetSender); // TODO correct port
            var       peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
            var       n1 = new PeerAddress(idSender, peerSocketAddress, firewallTcp, firewallUdp, false, PeerAddress.EmptyPeerSocketAddresses);

            return(n1);
        }
Пример #4
0
        /// <summary>
        /// // TODO document
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="tcsResponse"></param>
        /// <param name="message"></param>
        /// <param name="channelCreator"></param>
        /// <param name="idleTcpSeconds"></param>
        /// <param name="connectTimeoutMillis"></param>
        /// <param name="peerConnection"></param>
        /// <param name="timeoutHandler"></param>
        private async Task HandleRelayAsync(IInboundHandler handler, TaskCompletionSource <Message.Message> tcsResponse,
                                            Message.Message message, ChannelCreator channelCreator, int idleTcpSeconds, int connectTimeoutMillis,
                                            PeerConnection peerConnection, TimeoutFactory timeoutHandler)
        {
            var   taskPingDone = PingFirst(message.Recipient.PeerSocketAddresses);
            await taskPingDone;

            if (!taskPingDone.IsFaulted)
            {
                var recipient = PeerSocketAddress.CreateSocketTcp(taskPingDone.Result);
                var channel   = SendTcpCreateChannel(recipient, channelCreator, peerConnection, handler,
                                                     timeoutHandler, connectTimeoutMillis);
                await AfterConnectAsync(tcsResponse, message, channel, handler == null);

                // TODO add this before AfterConnect?
                var   taskResponse = tcsResponse.Task;
                await taskResponse;
                if (taskResponse.IsFaulted)
                {
                    if (taskResponse.Result != null &&
                        taskResponse.Result.Type != Message.Message.MessageType.User1)
                    {
                        // "clearInactivePeerSocketAddress"
                        var tmp = new List <PeerSocketAddress>();
                        foreach (var psa in message.Recipient.PeerSocketAddresses)
                        {
                            if (psa != null)
                            {
                                if (!psa.Equals(taskPingDone.Result))
                                {
                                    tmp.Add(psa);
                                }
                            }
                        }
                        message.SetPeerSocketAddresses(tmp);

                        await SendTcpAsync(handler, tcsResponse, message, channelCreator, idleTcpSeconds,
                                           connectTimeoutMillis, peerConnection);
                    }
                }
            }
            else
            {
                // .NET-specific:
                tcsResponse.SetException(new TaskFailedException("No relay could be contacted. <-> " + taskPingDone.Exception));
            }
        }
Пример #5
0
        private static Message CreateMessageSetPeerSocket()
        {
            IPAddress sampleAddress1 = IPAddress.Parse("192.168.1.1");
            IPAddress sampleAddress2 = IPAddress.Parse("255.255.255.255");
            IPAddress sampleAddress3 = IPAddress.Parse("127.0.0.1");
            IPAddress sampleAddress4 = IPAddress.Parse("0:1:2:3:4:5:6:7");
            IPAddress sampleAddress5 = IPAddress.Parse("7:6:5:4:3:2:1:0");

            var samplePsa1  = new PeerSocketAddress(sampleAddress1, 0, 0);
            var samplePsa2  = new PeerSocketAddress(sampleAddress2, 65535, 65535);
            var samplePsa3  = new PeerSocketAddress(sampleAddress3, 1, 1);
            var samplePsa4  = new PeerSocketAddress(sampleAddress4, 2, 2);
            var samplePsa5  = new PeerSocketAddress(sampleAddress5, 30, 40);
            var samplePsa6  = new PeerSocketAddress(sampleAddress1, 88, 88);
            var samplePsa7  = new PeerSocketAddress(sampleAddress2, 177, 177);
            var samplePsa8  = new PeerSocketAddress(sampleAddress3, 60000, 65000);
            var samplePsa9  = new PeerSocketAddress(sampleAddress4, 99, 100);
            var samplePsa10 = new PeerSocketAddress(sampleAddress5, 13, 1234);

            ICollection <PeerSocketAddress> sampleAddresses = new List <PeerSocketAddress>();

            sampleAddresses.Add(samplePsa1);
            sampleAddresses.Add(samplePsa2);
            sampleAddresses.Add(samplePsa3);
            sampleAddresses.Add(samplePsa4);
            sampleAddresses.Add(samplePsa5);
            sampleAddresses.Add(samplePsa6);
            sampleAddresses.Add(samplePsa7);
            sampleAddresses.Add(samplePsa8);
            sampleAddresses.Add(samplePsa9);
            sampleAddresses.Add(samplePsa10);

            // only 1 content is set, because per content, whole list is encoded
            var m = Utils2.CreateDummyMessage();

            m.SetPeerSocketAddresses(sampleAddresses);
            return(m);
        }
Пример #6
0
        /// <summary>
        /// Ping all relays of the receiver. The first one answering is picked
        /// as the responsible relay for this message.
        /// </summary>
        /// <param name="peerSocketAddresses">A collection of relay addresses.</param>
        /// <returns></returns>
        private Task <PeerSocketAddress> PingFirst(IEnumerable <PeerSocketAddress> peerSocketAddresses)
        {
            var tcsDone = new TaskCompletionSource <PeerSocketAddress>();

            var socketAddresses = peerSocketAddresses as PeerSocketAddress[] ?? peerSocketAddresses.ToArray();
            var forks           = new Task <PeerAddress> [socketAddresses.Count()];
            int index           = 0;

            foreach (var psa in socketAddresses)
            {
                if (psa != null)
                {
                    var socketAddress = PeerSocketAddress.CreateSocketUdp(psa);
                    var pingBuilder   = PingBuilderFactory.Create();
                    forks[index++] = pingBuilder
                                     .SetInetAddress(socketAddress.Address)
                                     .SetPort(socketAddress.Port)
                                     .Start(); // TODO TCS or Task needed?
                }
            }

            var ffk = new TcsForkJoin <Task <PeerAddress> >(1, true, new VolatileReferenceArray <Task <PeerAddress> >(forks));

            ffk.Task.ContinueWith(tfj =>
            {
                if (!tfj.IsFaulted)
                {
                    tcsDone.SetResult(ffk.First.Result.PeerSocketAddress);
                }
                else
                {
                    tcsDone.SetException(tfj.TryGetException());
                }
            });

            return(tcsDone.Task);
        }
Пример #7
0
        private bool DecodePayload(AlternativeCompositeByteBuf buffer)
        {
            Logger.Debug("About to pass message {0} to {1}. Buffer to read: {2}.", Message, Message.SenderSocket, buffer.ReadableBytes);

            if (!Message.HasContent())
            {
                return(true);
            }

            int        size;
            IPublicKey receivedPublicKey;

            while (_contentTypes.Count > 0)
            {
                Message.Content content = _contentTypes.Peek();
                Logger.Debug("Go for content: {0}.", content);

                switch (content)
                {
                case Message.Content.Integer:
                    if (buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    Message.SetIntValue(buffer.ReadInt());
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.Long:
                    if (buffer.ReadableBytes < Utils.Utils.LongByteSize)
                    {
                        return(false);
                    }
                    Message.SetLongValue(buffer.ReadLong());
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.Key:
                    if (buffer.ReadableBytes < Number160.ByteArraySize)
                    {
                        return(false);
                    }
                    var keyBytes = new sbyte[Number160.ByteArraySize];
                    buffer.ReadBytes(keyBytes);
                    Message.SetKey(new Number160(keyBytes));
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.BloomFilter:
                    if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                    {
                        return(false);
                    }
                    size = buffer.GetUShort(buffer.ReaderIndex);
                    if (buffer.ReadableBytes < size)
                    {
                        return(false);
                    }
                    Message.SetBloomFilter(new SimpleBloomFilter <Number160>(buffer));
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.SetNeighbors:
                    if (_neighborSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_neighborSize == -1)
                    {
                        _neighborSize = buffer.ReadByte();
                    }
                    if (_neighborSet == null)
                    {
                        _neighborSet = new NeighborSet(-1, new List <PeerAddress>(_neighborSize));
                    }
                    for (int i = _neighborSet.Size; i < _neighborSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }
                        int header = buffer.GetUShort(buffer.ReaderIndex);
                        size = PeerAddress.CalculateSize(header);
                        if (buffer.ReadableBytes < size)
                        {
                            return(false);
                        }
                        var pa = new PeerAddress(buffer);
                        _neighborSet.Add(pa);
                    }
                    Message.SetNeighborSet(_neighborSet);
                    LastContent   = _contentTypes.Dequeue();
                    _neighborSize = -1;     // TODO why here? not in prepareFinish()?
                    _neighborSet  = null;
                    break;

                case Message.Content.SetPeerSocket:
                    if (_peerSocketAddressSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_peerSocketAddressSize == -1)
                    {
                        _peerSocketAddressSize = buffer.ReadUByte();
                    }
                    if (_peerSocketAddresses == null)
                    {
                        _peerSocketAddresses = new List <PeerSocketAddress>(_peerSocketAddressSize);
                    }
                    for (int i = _peerSocketAddresses.Count; i < _peerSocketAddressSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        int  header = buffer.GetUByte(buffer.ReaderIndex);
                        bool isIPv4 = header == 0;     // TODO check if works
                        size = PeerSocketAddress.Size(isIPv4);
                        if (buffer.ReadableBytes < size + Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        // skip the ipv4/ipv6 header
                        buffer.SkipBytes(1);
                        _peerSocketAddresses.Add(PeerSocketAddress.Create(buffer, isIPv4));
                    }
                    Message.SetPeerSocketAddresses(_peerSocketAddresses);
                    LastContent            = _contentTypes.Dequeue();
                    _peerSocketAddressSize = -1;     // TODO why here? not in prepareFinish()?
                    _peerSocketAddresses   = null;
                    break;

                case Message.Content.SetKey640:
                    if (_keyCollectionSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyCollectionSize == -1)
                    {
                        _keyCollectionSize = buffer.ReadInt();
                    }
                    if (_keyCollection == null)
                    {
                        _keyCollection = new KeyCollection(new List <Number640>(_keyCollectionSize));
                    }
                    for (int i = _keyCollection.Size; i < _keyCollectionSize; i++)
                    {
                        if (buffer.ReadableBytes < 4 * Number160.ByteArraySize)
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];

                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        _keyCollection.Add(new Number640(locationKey, domainKey, contentKey, versionKey));
                    }
                    Message.SetKeyCollection(_keyCollection);
                    LastContent        = _contentTypes.Dequeue();
                    _keyCollectionSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyCollection     = null;
                    break;

                case Message.Content.MapKey640Data:
                    if (_mapSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_mapSize == -1)
                    {
                        _mapSize = buffer.ReadInt();
                    }
                    if (_dataMap == null)
                    {
                        _dataMap = new DataMap(new Dictionary <Number640, Data>(2 * _mapSize));
                    }
                    if (_data != null)
                    {
                        if (!_data.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _data = null;     // TODO why here? not in prepareFinish()?
                        _key  = null;
                    }
                    for (int i = _dataMap.Size; i < _mapSize; i++)
                    {
                        if (_key == null)
                        {
                            if (buffer.ReadableBytes < 4 * Number160.ByteArraySize)
                            {
                                return(false);
                            }
                            var me = new sbyte[Number160.ByteArraySize];
                            buffer.ReadBytes(me);
                            var locationKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var domainKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var contentKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var versionKey = new Number160(me);

                            _key = new Number640(locationKey, domainKey, contentKey, versionKey);
                        }
                        _data = Data.DeocdeHeader(buffer, _signatureFactory);
                        if (_data == null)
                        {
                            return(false);
                        }
                        _dataMap.BackingDataMap.Add(_key, _data);

                        if (!_data.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        // if we have signed the message, set the public key anyway, but only if we indicated so
                        if (Message.IsSign && Message.PublicKey(0) != null && _data.HasPublicKey &&
                            (_data.PublicKey == null || _data.PublicKey == PeerBuilder.EmptyPublicKey))
                        // TODO check empty key condition
                        {
                            _data.SetPublicKey(Message.PublicKey(0));
                        }
                        _data = null;     // TODO why here? not in prepareFinish()?
                        _key  = null;
                    }

                    Message.SetDataMap(_dataMap);
                    LastContent = _contentTypes.Dequeue();
                    _mapSize    = -1;  // TODO why here? not in prepareFinish()?
                    _dataMap    = null;
                    break;

                case Message.Content.MapKey640Keys:
                    if (_keyMap640KeysSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyMap640KeysSize == -1)
                    {
                        _keyMap640KeysSize = buffer.ReadInt();
                    }
                    if (_keyMap640Keys == null)
                    {
                        _keyMap640Keys = new KeyMap640Keys(new SortedDictionary <Number640, ICollection <Number160> >());
                        // TODO check TreeMap equivalent
                    }

                    const int meta = 4 * Number160.ByteArraySize;

                    for (int i = _keyMap640Keys.Size; i < _keyMap640KeysSize; i++)
                    {
                        if (buffer.ReadableBytes < meta + Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        size = buffer.GetUByte(buffer.ReaderIndex + meta);

                        if (buffer.ReadableBytes <
                            meta + Utils.Utils.ByteByteSize + (size * Number160.ByteArraySize))
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];
                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        int numBasedOn = buffer.ReadByte();
                        var value      = new HashSet <Number160>();
                        for (int j = 0; j < numBasedOn; j++)
                        {
                            buffer.ReadBytes(me);
                            var basedOnKey = new Number160(me);
                            value.Add(basedOnKey);
                        }

                        _keyMap640Keys.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value);
                    }

                    Message.SetKeyMap640Keys(_keyMap640Keys);
                    LastContent        = _contentTypes.Dequeue();
                    _keyMap640KeysSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyMap640Keys     = null;
                    break;

                case Message.Content.MapKey640Byte:
                    if (_keyMapByteSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyMapByteSize == -1)
                    {
                        _keyMapByteSize = buffer.ReadInt();
                    }
                    if (_keyMapByte == null)
                    {
                        _keyMapByte = new KeyMapByte(new Dictionary <Number640, sbyte>(2 * _keyMapByteSize));
                    }

                    for (int i = _keyMapByte.Size; i < _keyMapByteSize; i++)
                    {
                        if (buffer.ReadableBytes < 4 * Number160.ByteArraySize + 1)
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];
                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        sbyte value = buffer.ReadByte();
                        _keyMapByte.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value);
                    }

                    Message.SetKeyMapByte(_keyMapByte);
                    LastContent     = _contentTypes.Dequeue();
                    _keyMapByteSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyMapByte     = null;
                    break;

                case Message.Content.ByteBuffer:
                    if (_bufferSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_bufferSize == -1)
                    {
                        _bufferSize = buffer.ReadInt();
                    }
                    if (_buffer == null)
                    {
                        _buffer = new DataBuffer();
                    }

                    int already   = _buffer.AlreadyTransferred;
                    int remaining = _bufferSize - already;
                    // already finished
                    if (remaining != 0)
                    {
                        int read = _buffer.TransferFrom(buffer, remaining);
                        if (read != remaining)
                        {
                            Logger.Debug(
                                "Still looking for data. Indicating that its not finished yet. Already Transferred = {0}, Size = {1}.",
                                _buffer.AlreadyTransferred, _bufferSize);
                            return(false);
                        }
                    }

                    ByteBuf buf2 = AlternativeCompositeByteBuf.CompBuffer(_buffer.ToByteBufs());
                    Message.SetBuffer(new Buffer(buf2, _bufferSize));
                    LastContent = _contentTypes.Dequeue();
                    _bufferSize = -1;
                    _buffer     = null;
                    break;

                case Message.Content.SetTrackerData:
                    if (_trackerDataSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_trackerDataSize == -1)
                    {
                        _trackerDataSize = buffer.ReadUByte();
                    }
                    if (_trackerData == null)
                    {
                        _trackerData = new TrackerData(new Dictionary <PeerAddress, Data>(2 * _trackerDataSize));
                    }
                    if (_currentTrackerData != null)
                    {
                        if (!_currentTrackerData.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _currentTrackerData = null;
                    }
                    for (int i = _trackerData.Size; i < _trackerDataSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }

                        int header = buffer.GetUShort(buffer.ReaderIndex);
                        size = PeerAddress.CalculateSize(header);
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }
                        var pa = new PeerAddress(buffer);

                        _currentTrackerData = Data.DeocdeHeader(buffer, _signatureFactory);
                        if (_currentTrackerData == null)
                        {
                            return(false);
                        }
                        _trackerData.PeerAddresses.Add(pa, _currentTrackerData);
                        if (Message.IsSign)
                        {
                            _currentTrackerData.SetPublicKey(Message.PublicKey(0));
                        }
                        if (!_currentTrackerData.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _currentTrackerData = null;     // TODO why here?
                    }

                    Message.SetTrackerData(_trackerData);
                    LastContent      = _contentTypes.Dequeue();
                    _trackerDataSize = -1;
                    _trackerData     = null;
                    break;

                case Message.Content.PublicKey:     // fall-through
                case Message.Content.PublicKeySignature:
                    receivedPublicKey = _signatureFactory.DecodePublicKey(buffer);
                    if (content == Message.Content.PublicKeySignature)
                    {
                        if (receivedPublicKey == PeerBuilder.EmptyPublicKey)     // TODO check if works
                        {
                            // TODO throw InvalidKeyException
                            throw new SystemException("The public key cannot be empty.");
                        }
                    }
                    if (receivedPublicKey == null)
                    {
                        return(false);
                    }

                    Message.SetPublicKey(receivedPublicKey);
                    LastContent = _contentTypes.Dequeue();
                    break;

                default:
                    break;
                }
            }

            if (Message.IsSign)
            {
                var signatureEncode = _signatureFactory.SignatureCodec;
                size = signatureEncode.SignatureSize;
                if (buffer.ReadableBytes < size)
                {
                    return(false);
                }

                signatureEncode.Read(buffer);
                Message.SetReceivedSignature(signatureEncode);
            }
            return(true);
        }