Esempio n. 1
0
        /// <summary>
        /// Encodes a message object.
        /// The format looks as follows: 28 bit P2P version, 4 bit message type, 32 bit message ID, 8 bit message command,
        /// 160 bit senderSocket ID, 16 bit senderSocket TCP port, 16 bit senderSocket UDP port, 160 bit recipientSocket ID, 32 bit content types, 8 bit options.
        /// In total, the header is of size 58 bytes.
        /// </summary>
        /// <param name="buffer">The buffer to encode to.</param>
        /// <param name="message">The message with the header that will be encoded.</param>
        public static void EncodeHeader(AlternativeCompositeByteBuf buffer, Message message)
        {
            // TODO add log statemet, also in Java version
            int versionAndType = message.Version << 4 | ((int)message.Type & Utils.Utils.Mask0F); // TODO check if ordinal works

            buffer.WriteInt(versionAndType);                                                      // 4
            buffer.WriteInt(message.MessageId);                                                   // 8
            buffer.WriteByte(message.Command);                                                    // 9
            buffer.WriteBytes(message.Sender.PeerId.ToByteArray());                               // 29
            buffer.WriteShort((short)message.Sender.TcpPort);                                     // 31
            buffer.WriteShort((short)message.Sender.UdpPort);                                     // 33
            buffer.WriteBytes(message.Recipient.PeerId.ToByteArray());                            // 53
            buffer.WriteInt(EncodeContentTypes(message.ContentTypes));                            // 57
            buffer.WriteByte((sbyte)(message.Sender.Options << 4 | message.Options));             // 58 // TODO check if works
        }
Esempio n. 2
0
        /// <summary>
        /// Encodes a message object.
        /// The format looks as follows: 28 bit P2P version, 4 bit message type, 32 bit message ID, 8 bit message command,
        /// 160 bit senderSocket ID, 16 bit senderSocket TCP port, 16 bit senderSocket UDP port, 160 bit recipientSocket ID, 32 bit content types, 8 bit options.
        /// In total, the header is of size 58 bytes.
        /// </summary>
        /// <param name="buffer">The buffer to encode to.</param>
        /// <param name="message">The message with the header that will be encoded.</param>
        public static void EncodeHeader(AlternativeCompositeByteBuf buffer, Message message)
        {
            // TODO add log statemet, also in Java version
            int versionAndType = message.Version << 4 | ((int)message.Type & Utils.Utils.Mask0F); // TODO check if ordinal works

            buffer.WriteInt(versionAndType); // 4
            buffer.WriteInt(message.MessageId); // 8
            buffer.WriteByte(message.Command); // 9
            buffer.WriteBytes(message.Sender.PeerId.ToByteArray()); // 29
            buffer.WriteShort((short) message.Sender.TcpPort); // 31 
            buffer.WriteShort((short) message.Sender.UdpPort); // 33
            buffer.WriteBytes(message.Recipient.PeerId.ToByteArray()); // 53
            buffer.WriteInt(EncodeContentTypes(message.ContentTypes)); // 57
            buffer.WriteByte((sbyte) (message.Sender.Options << 4 | message.Options)); // 58 // TODO check if works
        }
Esempio n. 3
0
        private bool Loop(AlternativeCompositeByteBuf buffer)
        {
            MessageContentIndex next;

            while ((next = Message.ContentReferences.Peek2()) != null)
            {
                long            start   = buffer.WriterIndex;
                Message.Content content = next.Content;

                switch (content)
                {
                case Message.Content.Key:
                    buffer.WriteBytes(Message.Key(next.Index).ToByteArray());
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.Integer:
                    buffer.WriteInt(Message.IntAt(next.Index));
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.Long:
                    buffer.WriteLong(Message.LongAt(next.Index));
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetNeighbors:
                    var neighborSet = Message.NeighborsSet(next.Index);
                    // write length
                    buffer.WriteByte((sbyte)neighborSet.Size);
                    foreach (var neighbor in neighborSet.Neighbors)
                    {
                        buffer.WriteBytes(neighbor.ToByteArray());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetPeerSocket:
                    var list = Message.PeerSocketAddresses;
                    // write length
                    buffer.WriteByte((sbyte)list.Count);
                    foreach (var psa in list)
                    {
                        // write IP version flag
                        buffer.WriteByte(psa.IsIPv4 ? 0 : 1);
                        buffer.WriteBytes(psa.ToByteArray());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.BloomFilter:
                    var bf = Message.BloomFilter(next.Index);
                    bf.ToByteBuffer(buffer);
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetKey640:
                    var keys = Message.KeyCollection(next.Index);
                    // write length
                    buffer.WriteInt(keys.Size);
                    if (keys.IsConvert)
                    {
                        foreach (var key in keys.KeysConvert)
                        {
                            buffer.WriteBytes(keys.LocationKey.ToByteArray());
                            buffer.WriteBytes(keys.DomainKey.ToByteArray());
                            buffer.WriteBytes(key.ToByteArray());
                            buffer.WriteBytes(keys.VersionKey.ToByteArray());
                        }
                    }
                    else
                    {
                        foreach (var key in keys.Keys)
                        {
                            buffer.WriteBytes(key.LocationKey.ToByteArray());
                            buffer.WriteBytes(key.DomainKey.ToByteArray());
                            buffer.WriteBytes(key.ContentKey.ToByteArray());
                            buffer.WriteBytes(key.VersionKey.ToByteArray());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Data:
                    var dm = Message.DataMap(next.Index);
                    // write length
                    buffer.WriteInt(dm.Size);
                    if (dm.IsConvert)
                    {
                        foreach (var data in dm.DataMapConvert)
                        {
                            buffer.WriteBytes(dm.LocationKey.ToByteArray());
                            buffer.WriteBytes(dm.DomainKey.ToByteArray());
                            buffer.WriteBytes(data.Key.ToByteArray());
                            buffer.WriteBytes(dm.VersionKey.ToByteArray());

                            EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest());
                        }
                    }
                    else
                    {
                        foreach (var data in dm.BackingDataMap)
                        {
                            buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                            buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                            buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                            buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                            EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Keys:
                    var kmk = Message.KeyMap640Keys(next.Index);
                    // write length
                    buffer.WriteInt(kmk.Size);
                    foreach (var data in kmk.KeysMap)
                    {
                        buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                        buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                        buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                        buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                        // write number of based-on keys
                        buffer.WriteByte((sbyte)data.Value.Count);

                        // write based-on keys
                        foreach (var key in data.Value)
                        {
                            buffer.WriteBytes(key.ToByteArray());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Byte:
                    var kmb = Message.KeyMapByte(next.Index);
                    // write length
                    buffer.WriteInt(kmb.Size);
                    foreach (var data in kmb.KeysMap)
                    {
                        buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                        buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                        buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                        buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                        // write byte
                        buffer.WriteByte(data.Value);
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.ByteBuffer:
                    var b = Message.Buffer(next.Index);
                    if (!_resume)
                    {
                        buffer.WriteInt(b.Length);
                    }
                    // write length
                    int readable = b.Readable;
                    buffer.WriteBytes(b.BackingBuffer, readable);
                    if (b.IncRead(readable) == b.Length)
                    {
                        Message.ContentReferences.Dequeue();
                    }
                    else if (Message.IsStreaming())
                    {
                        Logger.Debug("Partial message of length {0} sent.", readable);
                        return(false);
                    }
                    else
                    {
                        const string description = "Larger buffer has been announced, but not in message streaming mode. This is wrong.";
                        Logger.Error(description);
                        throw new SystemException(description);
                    }
                    break;

                case Message.Content.SetTrackerData:
                    var td = Message.TrackerData(next.Index);
                    // write length
                    buffer.WriteByte((sbyte)td.PeerAddresses.Count);      // TODO remove cast
                    foreach (var data in td.PeerAddresses)
                    {
                        var me = data.Key.ToByteArray();
                        buffer.WriteBytes(me);

                        var d = data.Value.Duplicate();
                        EncodeData(buffer, d, false, !Message.IsRequest());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.PublicKeySignature:
                    // flag to encode public key
                    Message.SetHintSign();
                    // then, do the regular public key stuff -> no break
                    goto case Message.Content.PublicKey;     // TODO check, else duplicate code

                case Message.Content.PublicKey:
                    var pk = Message.PublicKey(next.Index);
                    _signatureFactory.EncodePublicKey(pk, buffer);
                    Message.ContentReferences.Dequeue();
                    break;

                default:
                    throw new SystemException("Unknown type: " + next.Content);
                }

                Logger.Debug("Wrote in encoder for {0} {1}.", content, buffer.WriterIndex - start);
            }
            return(true);
        }