public static byte[] Serialize(ref IMessage Message) { var Size = SizeOf(ref Message); var Stream = new DnStream(Size); var Pointers = new Dictionary <string, ushort>(); Stream.SetUShort(Message.ID); Stream.SetBit((byte)Message.MessageType); Stream.SetBits(4, (byte)Message.OperationCode); Stream.SetBit((byte)Message.AuthoritativeAnswer); Stream.SetBit(Convert.ToByte(Message.Truncated)); Stream.SetBit(Convert.ToByte(Message.RecursionDesired)); Stream.SetBit(Convert.ToByte(Message.RecursionAvailable)); Stream.SetBit(Message.Zero); Stream.SetBit(Convert.ToByte(Message.AuthenticatedData)); Stream.SetBit(Convert.ToByte(Message.CheckingDisabled)); Stream.SetBits(4, (byte)Message.ResponseCode); Stream.SetUShort((ushort)Message.Questions.Count()); Stream.SetUShort((ushort)Message.Answers.Count()); Stream.SetUShort((ushort)Message.Authority.Count()); Stream.SetUShort((ushort)Message.Additional.Count()); Set(ref Stream, ref Pointers, Message.Questions); Set(ref Stream, ref Pointers, Message.Answers); Set(ref Stream, ref Pointers, Message.Authority); Set(ref Stream, ref Pointers, Message.Additional); return(Stream.ToArray()); }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IEnumerable <string> Labels) { var Domain = string.Join('.', Labels); foreach (var Label in Labels) { var SubDomain = Domain.Substring(Domain.IndexOf(Label)); if (Pointers.ContainsKey(SubDomain)) { Stream.SetBits(2, (byte)LabelType.Compressed); var Bytes = new byte[2]; BinaryPrimitives.WriteUInt16BigEndian(Bytes, Pointers[SubDomain]); Stream.SetBits(6, Bytes[0]); Stream.SetByte(Bytes[1]); return; } else { Pointers.Add(SubDomain, Stream.BytePosition); Stream.SetBits(2, (byte)LabelType.Normal); Stream.SetBits(6, (byte)Label.Length); Stream.SetString(Label); } } Stream.SetByte(0); }