byte[] BuildRequest(Message request) { // Always have a query ID. if (request.Id == 0) { request.Id = this.NextQueryId(); } // Add an OPT if not already present. var opt = request.AdditionalRecords.OfType <OPTRecord>().FirstOrDefault(); if (opt == null) { opt = new OPTRecord(); request.AdditionalRecords.Add(opt); } // Keep the connection alive. if (!opt.Options.Any(o => o.Type == EdnsOptionType.Keepalive)) { var keepalive = new EdnsKeepaliveOption { Timeout = TimeSpan.FromMinutes(2) }; opt.Options.Add(keepalive); } ; // Always use padding. Must be the last transform. if (!opt.Options.Any(o => o.Type == EdnsOptionType.Padding)) { var paddingOption = new EdnsPaddingOption(); opt.Options.Add(paddingOption); var need = BlockLength - ((request.Length() + 2) % BlockLength); if (need > 0) { paddingOption.Padding = new byte[need]; rng.NextBytes(paddingOption.Padding); } } ; using (var tcpRequest = new MemoryStream()) { tcpRequest.WriteByte(0); // two byte length prefix tcpRequest.WriteByte(0); request.Write(tcpRequest); // udpRequest var length = (ushort)(tcpRequest.Length - 2); tcpRequest.Position = 0; tcpRequest.WriteByte((byte)(length >> 8)); tcpRequest.WriteByte((byte)(length)); return(tcpRequest.ToArray()); } }
public void Roundtrip_Empty() { var opt1 = new OPTRecord(); var expected = new EdnsKeepaliveOption(); Assert.AreEqual(EdnsOptionType.Keepalive, expected.Type); Assert.AreEqual(false, expected.Timeout.HasValue); opt1.Options.Add(expected); var opt2 = (OPTRecord) new ResourceRecord().Read(opt1.ToByteArray()); var actual = (EdnsKeepaliveOption)opt2.Options[0]; Assert.AreEqual(expected.Type, actual.Type); Assert.AreEqual(expected.Timeout.HasValue, actual.Timeout.HasValue); }
public void Roundtrip() { var opt1 = new OPTRecord(); var expected = new EdnsKeepaliveOption { Timeout = TimeSpan.FromSeconds(3) }; Assert.AreEqual(EdnsOptionType.Keepalive, expected.Type); opt1.Options.Add(expected); var opt2 = (OPTRecord) new ResourceRecord().Read(opt1.ToByteArray()); var actual = (EdnsKeepaliveOption)opt2.Options[0]; Assert.AreEqual(expected.Type, actual.Type); Assert.AreEqual(expected.Timeout.Value, actual.Timeout.Value); }