/* https://www.rfc-editor.org/rfc/rfc8005.html HIP RR Storage Format The RDATA for a HIP RR consists of a PK Algorithm Type, the HIT length, a HIT, a PK (i.e., an HI), and optionally one or more RVSs. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | HIT length | PK algorithm | PK length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | ~ HIT ~ | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | +-+-+-+-+-+-+-+-+-+-+-+ + | Public Key | ~ ~ | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | ~ Rendezvous Servers ~ | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | +-+-+-+-+-+-+-+ The HIT length, PK algorithm, PK length, HIT, and Public Key fields are REQUIRED. The Rendezvous Server field is OPTIONAL. */ using MailSharp.DNS.Records; namespace MailSharp.DNS.Records; public record RecordHIP : DnsRecord { public byte HitLength { get; init; } public byte PkAlgorithm { get; init; } public ushort PkLength { get; init; } public byte[] HostIdentityTag { get; init; } = Array.Empty(); public byte[] PublicKey { get; init; } = Array.Empty(); public List RendezvousServers { get; init; } = []; public RecordHIP(RecordReader rr) : base(rr) { ushort rdlength = rr.ReadUInt16(-2); HitLength = rr.ReadByte(); PkAlgorithm = rr.ReadByte(); PkLength = rr.ReadUInt16(); HostIdentityTag = rr.ReadBytes(HitLength); PublicKey = rr.ReadBytes(PkLength); while (rr.Position < rdlength) RendezvousServers.Add(rr.ReadDomainName()); } public override string ToString() { string hit = Convert.ToBase64String(HostIdentityTag); string pk = Convert.ToBase64String(PublicKey); string srv = RendezvousServers.Count == 0 ? "" : " " + string.Join(" ", RendezvousServers); return $"{PkAlgorithm} {hit} {pk}{srv}"; } }