/// <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 }
/// <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 }
public static sbyte[] ReadJavaBytes(byte[] bytes) { AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(bytes.ToSByteArray()); return(ExtractBytes(buf).ToSByteArray()); }
/// <summary> /// Converts data to a byte buffer. The first two bytes contain the size of this simple bloom filter. Thus, the bloom filter can only be of length 65536. /// </summary> /// <param name="buffer"></param> public void ToByteBuffer(AlternativeCompositeByteBuf buffer) { sbyte[] tmp = BitArray.ToByteArray(); int currentByteArraySize = tmp.Length; buffer.WriteShort((short)(_byteArraySize + SizeHeader)); buffer.WriteInt(ExpectedElements); buffer.WriteBytes(tmp); buffer.WriteZero(_byteArraySize - currentByteArraySize); }
/// <summary> /// Decodes a message from the provided byte array. /// </summary> /// <param name="bytes">The message bytes from Java encoding.</param> /// <returns>The .NET message version.</returns> public static Message DecodeMessage(byte[] bytes) { var decoder = new Decoder(null); // mock a non-working ChannelHandlerContext var pipeline = new Pipeline(); var channel = new MyTcpClient(new IPEndPoint(IPAddress.Any, 0), pipeline); var session = new PipelineSession(channel, pipeline, new List <IInboundHandler>(), new List <IOutboundHandler>()); var ctx = new ChannelHandlerContext(channel, session); // create dummy sender for decoding var message = Utils2.CreateDummyMessage(); AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(bytes.ToSByteArray()); decoder.Decode(ctx, buf, message.Recipient.CreateSocketTcp(), message.Sender.CreateSocketTcp()); return(decoder.Message); }
public void TestEncodeBytes() { AlternativeCompositeByteBuf buffer = AlternativeCompositeByteBuf.CompBuffer(); // Java byte is signed sbyte[] byteArray = new sbyte[256]; for (int i = 0, b = sbyte.MinValue; b <= sbyte.MaxValue; i++, b++) // -128 ... 127 { byteArray[i] = (sbyte)b; } buffer.WriteBytes(byteArray); var bytes = InteropUtil.ExtractBytes(buffer); bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes); Assert.IsTrue(interopResult); }
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); }