public override async Task DoReceiveMessageAsync() { // receive bytes UdpReceiveResult udpRes; try { udpRes = await _udpClient.ReceiveAsync().WithCancellation(CloseToken); } catch (OperationCanceledException) { // the socket has been closed return; } var buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(udpRes.Buffer.ToSByteArray()); var localEp = (IPEndPoint)Socket.LocalEndPoint; RemoteEndPoint = udpRes.RemoteEndPoint; var dgram = new DatagramPacket(buf, localEp, RemoteEndPoint); Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); // execute inbound pipeline if (Session.IsTimedOut) { return; } Session.Read(dgram); Session.Reset(); }
private void VerifySignature(AlternativeCompositeByteBuf buffer, long readerBefore, long len, bool donePayload) // TODO throw exceptions? { if (!Message.IsSign) { return; } // if we read the complete data, we also read the signature // for the verification, we should not used this for the signature var length = donePayload ? len - (Number160.ByteArraySize + Number160.ByteArraySize) : len; MemoryStream[] byteBuffers = null; // TODO no clue how to port this var signature = _signatureFactory.Update(Message.PublicKey(0), byteBuffers); // TODO what's going on here? if (donePayload) { byte[] signatureReceived = Message.ReceivedSignature.Encode(); if (true) // TODO implement .NET signature verification { // set the public key only if the signature is correct Message.SetVerified(); Logger.Debug("Signature check OK."); } else { Logger.Warn("Signature check NOT OK. Message: {0}.", Message); } } }
/// <summary> /// Decodes 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 decode from.</param> /// <param name="recipientSocket">The recipientSocket of the message.</param> /// <param name="senderSocket">The senderSocket of the packet, which has been set in the socket class.</param> // TODO check if true /// <returns>The partial message where only the header fields are set.</returns> public static Message DecodeHeader(AlternativeCompositeByteBuf buffer, IPEndPoint recipientSocket, IPEndPoint senderSocket) { Logger.Debug("Decode message. Recipient: {0}, Sender: {1}", recipientSocket, senderSocket); var message = new Message(); int versionAndType = buffer.ReadInt(); // 4 message.SetVersion(versionAndType >> 4); message.SetType((Message.MessageType)(versionAndType & Utils.Utils.Mask0F)); // TODO does this work? (2x) message.SetMessageId(buffer.ReadInt()); // 8 message.SetCommand(buffer.ReadByte()); // 9 // TODO check conversion with Java version var senderId = ReadId(buffer); // 29 int tcpPort = buffer.ReadUShort(); // 31 // TODO check if should be read as short (same as encode) int udpPort = buffer.ReadUShort(); // 33 var recipientId = ReadId(buffer); // 53 int contentTypes = buffer.ReadInt(); // 57 int options = buffer.ReadUByte(); // 58 // TODO check if should be read as unsigned/signed message.SetRecipient(new PeerAddress(recipientId, recipientSocket)); message.HasContent(contentTypes != 0); message.SetContentType(DecodeContentTypes(contentTypes, message)); message.SetOptions(options & Utils.Utils.Mask0F); // set the address as we see it, important for port forwarding identification int senderOptions = options >> 4; var pa = new PeerAddress(senderId, senderSocket.Address, tcpPort, udpPort, senderOptions); message.SetSender(pa); message.SetSenderSocket(senderSocket); message.SetRecipientSocket(recipientSocket); return(message); }
private static Buffer CreateTestBuffer() { var acbb = AlternativeCompositeByteBuf.CompBuffer(); acbb.WriteBytes(TestRawBytes); return(new Buffer(acbb)); }
private bool DecodeHeader(AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender) { if (Message == null) { if (buffer.ReadableBytes < MessageHeaderCodec.HeaderSize) { // we don't have the header yet, we need the full header first // wait for more data return(false); } Message = MessageHeaderCodec.DecodeHeader(buffer, recipient, sender); // we have set the content types already Message.SetPresetContentTypes(true); foreach (var content in Message.ContentTypes) { if (content == Message.Content.Empty) { break; } if (content == Message.Content.PublicKeySignature) { Message.SetHintSign(); } _contentTypes.Enqueue(content); } Logger.Debug("Parsed message {0}.", Message); return(true); } return(false); }
public static sbyte[] ReadJavaBytes(byte[] bytes) { AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(bytes.ToSByteArray()); return(ExtractBytes(buf).ToSByteArray()); }
/// <summary> /// Decodes 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 decode from.</param> /// <param name="recipientSocket">The recipientSocket of the message.</param> /// <param name="senderSocket">The senderSocket of the packet, which has been set in the socket class.</param> // TODO check if true /// <returns>The partial message where only the header fields are set.</returns> public static Message DecodeHeader(AlternativeCompositeByteBuf buffer, IPEndPoint recipientSocket, IPEndPoint senderSocket) { Logger.Debug("Decode message. Recipient: {0}, Sender: {1}", recipientSocket, senderSocket); var message = new Message(); int versionAndType = buffer.ReadInt(); // 4 message.SetVersion(versionAndType >> 4); message.SetType((Message.MessageType)(versionAndType & Utils.Utils.Mask0F)); // TODO does this work? (2x) message.SetMessageId(buffer.ReadInt()); // 8 message.SetCommand(buffer.ReadByte()); // 9 // TODO check conversion with Java version var senderId = ReadId(buffer); // 29 int tcpPort = buffer.ReadUShort(); // 31 // TODO check if should be read as short (same as encode) int udpPort = buffer.ReadUShort(); // 33 var recipientId = ReadId(buffer); // 53 int contentTypes = buffer.ReadInt(); // 57 int options = buffer.ReadUByte(); // 58 // TODO check if should be read as unsigned/signed message.SetRecipient(new PeerAddress(recipientId, recipientSocket)); message.HasContent(contentTypes != 0); message.SetContentType(DecodeContentTypes(contentTypes, message)); message.SetOptions(options & Utils.Utils.Mask0F); // set the address as we see it, important for port forwarding identification int senderOptions = options >> 4; var pa = new PeerAddress(senderId, senderSocket.Address, tcpPort, udpPort, senderOptions); message.SetSender(pa); message.SetSenderSocket(senderSocket); message.SetRecipientSocket(recipientSocket); return message; }
/// <summary> /// Reads a <see cref="Number160"/> from a buffer. /// </summary> /// <param name="buffer"></param> /// <returns></returns> private static Number160 ReadId(AlternativeCompositeByteBuf buffer) { var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); return(new Number160(me)); }
public Buffer Reply(PeerAddress sender, Buffer requestBuffer, bool complete) { int i = requestBuffer.BackingBuffer.ReadInt(); Console.WriteLine("Got {0}.", i); var buffer = AlternativeCompositeByteBuf.CompBuffer().WriteInt(i); return(new Buffer(buffer)); }
public static byte[] ExtractBytes(AlternativeCompositeByteBuf buf) { var buffer = buf.NioBuffer(); buffer.Position = 0; var bytes = new byte[buffer.Remaining()]; buffer.Get(bytes, 0, bytes.Length); return bytes; }
/// <summary> /// Encodes a provided message into a byte array. /// </summary> /// <param name="message">The message to be encoded.</param> /// <returns>The encoded message as byte array.</returns> public static byte[] EncodeMessage(Message message) { var encoder = new Encoder(null); AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer(); encoder.Write(buf, message, null); return(InteropUtil.ExtractBytes(buf)); }
public async void TestOrder() { Peer sender = null; Peer recv1 = null; ChannelCreator cc = null; try { sender = new PeerBuilder(new Number160("0x50")) .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask()) .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(2525, 2525)) .SetP2PId(55) .SetPorts(2525) .Start(); recv1 = new PeerBuilder(new Number160("0x20")) .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask()) .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(9099, 9099)) .SetP2PId(55) .SetPorts(8088) .Start(); recv1.RawDataReply(new TestOrderRawDataReply()); for (int i = 0; i < 500; i++) { cc = await sender.ConnectionBean.Reservation.CreateAsync(0, 1); var sendDirectBuilder = new SendDirectBuilder(sender, (PeerAddress)null); var buffer = AlternativeCompositeByteBuf.CompBuffer().WriteInt(i); sendDirectBuilder.SetBuffer(new Buffer(buffer)); sendDirectBuilder.SetIsStreaming(); var tr = sender.DirectDataRpc.SendAsync(recv1.PeerAddress, sendDirectBuilder, cc); Core.Utils.Utils.AddReleaseListener(cc, tr); tr.ContinueWith(t => { int j = t.Result.Buffer(0).BackingBuffer.ReadInt(); Console.WriteLine("Received {0}.", j); }); } } finally { if (sender != null) { sender.ShutdownAsync().Wait(); } if (recv1 != null) { recv1.ShutdownAsync().Wait(); } if (cc != null) { cc.ShutdownAsync().Wait(); } } }
protected static Buffer CreateSampleBuffer() { var acbb = AlternativeCompositeByteBuf.CompBuffer(); for (int i = 0; i < BufferSizeBytes; i++) { acbb.WriteByte(i % 256); } return(new Buffer(acbb)); }
private void DecodeSignature(AlternativeCompositeByteBuf buffer, long readerBefore, bool donePayload) { var readerAfter = buffer.ReaderIndex; var len = readerAfter - readerBefore; if (len > 0) { VerifySignature(buffer, readerBefore, len, donePayload); } }
/// <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); }
public DatagramPacket(AlternativeCompositeByteBuf content, IPEndPoint recipient, IPEndPoint sender) { if (content == null) { throw new NullReferenceException("content"); } _content = content; _recipient = recipient; _sender = sender; }
public static byte[] ExtractBytes(AlternativeCompositeByteBuf buf) { var buffer = buf.NioBuffer(); buffer.Position = 0; var bytes = new byte[buffer.Remaining()]; buffer.Get(bytes, 0, bytes.Length); return(bytes); }
public DatagramPacket(AlternativeCompositeByteBuf content, IPEndPoint recipient, IPEndPoint sender) { if (content == null) { throw new NullReferenceException("content"); } _content = content; _recipient = recipient; _sender = sender; }
private void EncodeData(AlternativeCompositeByteBuf buffer, Data data, bool isConvertMeta, bool isReply) { data = isConvertMeta ? data.DuplicateMeta() : data.Duplicate(); if (isReply) { var ttl = (int)((data.ExpirationMillis - Convenient.CurrentTimeMillis()) / 1000); data.SetTtlSeconds(ttl < 0 ? 0 : ttl); } data.EncodeHeader(buffer, _signatureFactory); data.EncodeBuffer(buffer); data.EncodeDone(buffer, _signatureFactory, Message.PrivateKey); }
protected override async Task ProcessRequestAsync(object state) { var udpRes = (UdpReceiveResult)state; // prepare new session var buf = AlternativeCompositeByteBuf.CompBuffer(); var session = Pipeline.CreateNewServerSession(this); session.TriggerActive(); // process content buf.WriteBytes(udpRes.Buffer.ToSByteArray()); var localEp = (IPEndPoint)_udpClient.Client.LocalEndPoint; var remoteEp = udpRes.RemoteEndPoint; var dgram = new DatagramPacket(buf, localEp, remoteEp); Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); // execute inbound pipeline var readRes = session.Read(dgram); // resets timeout if (session.IsTimedOut) { session.TriggerInactive(); return; } // execute outbound pipeline var writeRes = session.Write(readRes); // resets timeout if (session.IsTimedOut) { session.TriggerInactive(); return; } // send back var bytes = ConnectionHelper.ExtractBytes(writeRes); await _udpClient.SendAsync(bytes, bytes.Length, remoteEp); NotifyWriteCompleted(); // resets timeout Logger.Debug("Sent {0} : {1}", Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); session.TriggerInactive(); }
/// <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 void TestDecodeByte() { var bytes = JarRunner.RequestJavaBytes(); var buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(bytes.ToSByteArray()); // Java byte is signed for (int i = sbyte.MinValue; i <= sbyte.MaxValue; i++) // -128 ... 127 { sbyte b = buf.ReadByte(); Assert.IsTrue(i == b); } }
/// <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 void TestEncodeByte() { var buffer = AlternativeCompositeByteBuf.CompBuffer(); // Java byte is signed for (int i = sbyte.MinValue; i <= sbyte.MaxValue; i++) // -128 ... 127 { buffer.WriteByte((sbyte)i); } var bytes = InteropUtil.ExtractBytes(buffer); bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes); Assert.IsTrue(interopResult); }
/// <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(); }
public bool Decode(ChannelHandlerContext ctx, AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender) { Logger.Debug("Decoding of TomP2P starts now. Readable: {0}.", buffer.ReadableBytes); try { long readerBefore = buffer.ReaderIndex; // set the sender of this message for handling timeout var attrInetAddr = ctx.Attr(InetAddressKey); attrInetAddr.Set(sender); if (Message == null) { bool doneHeader = DecodeHeader(buffer, recipient, sender); if (doneHeader) { // store the sender as an attribute var attrPeerAddr = ctx.Attr(PeerAddressKey); attrPeerAddr.Set(Message.Sender); Message.SetIsUdp(ctx.Channel.IsUdp); if (Message.IsFireAndForget() && Message.IsUdp) { TimeoutFactory.RemoveTimeout(ctx); } } else { return(false); } } bool donePayload = DecodePayload(buffer); //DecodeSignature(buffer, readerBefore, donePayload); // TODO discardSomeReadBytes -> performance improvement return(donePayload); } catch (Exception ex) { ctx.FireExceptionCaught(ex); Console.WriteLine(ex.ToString()); return(true); } }
public override void Read(ChannelHandlerContext ctx, object msg) { // .NET-specific: use a content wrapper for TCP, similar to TomP2PSinglePacketUdp var piece = msg as StreamPiece; if (piece == null) { //ctx.FireRead(msg); return; } var buf = piece.Content; var sender = piece.Sender; var recipient = piece.Recipient; Logger.Debug("{0}: Cumulating TCP stream piece.", this); try { if (_cumulation == null) { _cumulation = AlternativeCompositeByteBuf.CompBuffer(buf); } else { // add to overhead from last TCP packet _cumulation.AddComponent(buf); } Decoding(ctx, sender, recipient); } catch (Exception) { Logger.Error("Error in TCP decoding."); throw; } finally { // If the currently read buffer is read, it can be deallocated. // In case another TCP packet follows, a new buffer is created. if (_cumulation != null && !_cumulation.IsReadable) { _cumulation = null; // Java: no need to discard bytes as this was done in the decoder already } } }
public bool Decode(ChannelHandlerContext ctx, AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender) { Logger.Debug("Decoding of TomP2P starts now. Readable: {0}.", buffer.ReadableBytes); try { long readerBefore = buffer.ReaderIndex; // set the sender of this message for handling timeout var attrInetAddr = ctx.Attr(InetAddressKey); attrInetAddr.Set(sender); if (Message == null) { bool doneHeader = DecodeHeader(buffer, recipient, sender); if (doneHeader) { // store the sender as an attribute var attrPeerAddr = ctx.Attr(PeerAddressKey); attrPeerAddr.Set(Message.Sender); Message.SetIsUdp(ctx.Channel.IsUdp); if (Message.IsFireAndForget() && Message.IsUdp) { TimeoutFactory.RemoveTimeout(ctx); } } else { return false; } } bool donePayload = DecodePayload(buffer); //DecodeSignature(buffer, readerBefore, donePayload); // TODO discardSomeReadBytes -> performance improvement return donePayload; } catch (Exception ex) { ctx.FireExceptionCaught(ex); Console.WriteLine(ex.ToString()); return true; } }
public void TestDecodeBytes() { var bytes = JarRunner.RequestJavaBytes(); var buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(bytes.ToSByteArray()); // Java byte is signed var byteArray = new sbyte[256]; buf.ReadBytes(byteArray); for (int i = 0, b = sbyte.MinValue; i <= sbyte.MaxValue; i++, b++) // -128 ... 127 { Assert.IsTrue(b == byteArray[i]); } }
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); }
/// <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 override void Read(ChannelHandlerContext ctx, object msg) { // .NET-specific: use a content wrapper for TCP, similar to TomP2PSinglePacketUdp var piece = msg as StreamPiece; if (piece == null) { //ctx.FireRead(msg); return; } var buf = piece.Content; var sender = piece.Sender; var recipient = piece.Recipient; Logger.Debug("{0}: Cumulating TCP stream piece.", this); try { if (_cumulation == null) { _cumulation = AlternativeCompositeByteBuf.CompBuffer(buf); } else { // add to overhead from last TCP packet _cumulation.AddComponent(buf); } Decoding(ctx, sender, recipient); } catch (Exception) { Logger.Error("Error in TCP decoding."); throw; } finally { // If the currently read buffer is read, it can be deallocated. // In case another TCP packet follows, a new buffer is created. if (_cumulation != null && !_cumulation.IsReadable) { _cumulation = null; // Java: no need to discard bytes as this was done in the decoder already } } }
public override async Task DoReceiveMessageAsync() { // TODO find zero-copy way, use same buffer // receive bytes var bytesRecv = new byte[256]; var buf = AlternativeCompositeByteBuf.CompBuffer(); var stream = _tcpClient.GetStream(); var pieceCount = 0; do { Array.Clear(bytesRecv, 0, bytesRecv.Length); buf.Clear(); int nrBytes; try { nrBytes = await stream.ReadAsync(bytesRecv, 0, bytesRecv.Length).WithCancellation(CloseToken); } catch (OperationCanceledException) { // the socket has been closed return; } buf.WriteBytes(bytesRecv.ToSByteArray(), 0, nrBytes); var localEp = (IPEndPoint)Socket.LocalEndPoint; RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint; var piece = new StreamPiece(buf, localEp, RemoteEndPoint); Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece, Convenient.ToHumanReadable(nrBytes), Convenient.ToString(bytesRecv)); // execute inbound pipeline, per piece (reset session!) if (Session.IsTimedOut) { return; } Session.Read(piece); Session.Reset(); } while (!IsClosed && stream.DataAvailable && !Session.IsTimedOut); }
/// <summary> /// Decodes a <see cref="PeerSocketAddress"/> from a buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="isIPv4">Whether the address is IPv4 or IPv6.</param> /// <returns>The <see cref="PeerSocketAddress"/> and the new offset.</returns> public static PeerSocketAddress Create(AlternativeCompositeByteBuf buffer, bool isIPv4) { int tcpPort = buffer.ReadUShort(); int udpPort = buffer.ReadUShort(); IPAddress address; sbyte[] me; if (isIPv4) { me = new sbyte[Utils.Utils.IPv4Bytes]; buffer.ReadBytes(me); address = Utils.Utils.Inet4AddressFromBytes(me, 0); } else { me = new sbyte[Utils.Utils.IPv6Bytes]; buffer.ReadBytes(me); address = Utils.Utils.Inet6AddressFromBytes(me, 0); } return(new PeerSocketAddress(address, tcpPort, udpPort, buffer.ReaderIndex)); }
public bool Write(AlternativeCompositeByteBuf buffer, Message message, ISignatureCodec signatureCodec) { Message = message; Logger.Debug("Message for outbound {0}.", message); if (!_header) { MessageHeaderCodec.EncodeHeader(buffer, message); _header = true; } else { Logger.Debug("Send a follow-up message {0}.", message); _resume = true; } bool done = Loop(buffer); Logger.Debug("Message encoded {0}.", message); // write out what we have if (buffer.IsReadable && done) { // check if message needs to be signed if (message.IsSign) { // we sign if we did not provide a signature already if (signatureCodec == null) { signatureCodec = _signatureFactory.Sign(message.PrivateKey, buffer); } // in case of relay, we have a signature, so we need to resuse this signatureCodec.Write(buffer); } } return(done); }
private static Message CreateMessageByteBuffer() { // write some random bytes var buf = AlternativeCompositeByteBuf.CompBuffer(); for (int i = 0; i < 300; i++) { switch (i % 3) { case 0: buf.WriteBytes(_sampleBytes1); break; case 1: buf.WriteBytes(_sampleBytes2); break; case 2: buf.WriteBytes(_sampleBytes3); break; } } // decompose buffer and use the resulting 8 ByteBufs in the list var decoms = buf.Decompose(0, buf.ReadableBytes); var m = Utils2.CreateDummyMessage(); m.SetBuffer(new Buffer(decoms[0])); m.SetBuffer(new Buffer(decoms[1])); m.SetBuffer(new Buffer(decoms[2])); m.SetBuffer(new Buffer(decoms[3])); m.SetBuffer(new Buffer(decoms[4])); m.SetBuffer(new Buffer(decoms[5])); m.SetBuffer(new Buffer(decoms[6])); m.SetBuffer(new Buffer(decoms[7])); return(m); }
private void VerifySignature(AlternativeCompositeByteBuf buffer, long readerBefore, long len, bool donePayload) // TODO throw exceptions? { if (!Message.IsSign) { return; } // if we read the complete data, we also read the signature // for the verification, we should not used this for the signature var length = donePayload ? len - (Number160.ByteArraySize + Number160.ByteArraySize) : len; MemoryStream[] byteBuffers = null; // TODO no clue how to port this var signature = _signatureFactory.Update(Message.PublicKey(0), byteBuffers); // TODO what's going on here? if (donePayload) { byte[] signatureReceived = Message.ReceivedSignature.Encode(); if (true) // TODO implement .NET signature verification { // set the public key only if the signature is correct Message.SetVerified(); Logger.Debug("Signature check OK."); } else { Logger.Warn("Signature check NOT OK. Message: {0}.", Message); } } }
public override void ChannelInactive(ChannelHandlerContext ctx) { var sender = ctx.Channel.RemoteEndPoint; var recipient = ctx.Channel.LocalEndPoint; try { if (_cumulation != null) { Decoding(ctx, sender, recipient); } } catch (Exception ex) { Logger.Error("Error in TCP decoding. (Inactive)", ex); throw; } finally { _cumulation = null; // TODO ctx.FireInactive needed? } }
private bool DecodeHeader(AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender) { if (Message == null) { if (buffer.ReadableBytes < MessageHeaderCodec.HeaderSize) { // we don't have the header yet, we need the full header first // wait for more data return false; } Message = MessageHeaderCodec.DecodeHeader(buffer, recipient, sender); // we have set the content types already Message.SetPresetContentTypes(true); foreach (var content in Message.ContentTypes) { if (content == Message.Content.Empty) { break; } if (content == Message.Content.PublicKeySignature) { Message.SetHintSign(); } _contentTypes.Enqueue(content); } Logger.Debug("Parsed message {0}.", Message); return true; } return false; }
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; }
private void DecodeSignature(AlternativeCompositeByteBuf buffer, long readerBefore, bool donePayload) { var readerAfter = buffer.ReaderIndex; var len = readerAfter - readerBefore; if (len > 0) { VerifySignature(buffer, readerBefore, len, donePayload); } }
/// <summary> /// Reads a <see cref="Number160"/> from a buffer. /// </summary> /// <param name="buffer"></param> /// <returns></returns> private static Number160 ReadId(AlternativeCompositeByteBuf buffer) { var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); return new Number160(me); }