/// <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> /// 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> /// 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)); }