mirror of
https://github.com/netchx/netch.git
synced 2026-05-09 22:54:03 +08:00
done
This commit is contained in:
128
Netch/3rd/DnsClient.NET/Protocol/Options/OptRecord.cs
Normal file
128
Netch/3rd/DnsClient.NET/Protocol/Options/OptRecord.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
namespace DnsClient.Protocol.Options
|
||||
{
|
||||
/* https://tools.ietf.org/html/rfc6891#section-4.3
|
||||
6.1.2. Wire Format
|
||||
|
||||
An OPT RR has a fixed part and a variable set of options expressed as
|
||||
{attribute, value} pairs. The fixed part holds some DNS metadata,
|
||||
and also a small collection of basic extension elements that we
|
||||
expect to be so popular that it would be a waste of wire space to
|
||||
encode them as {attribute, value} pairs.
|
||||
|
||||
The fixed part of an OPT RR is structured as follows:
|
||||
|
||||
+------------+--------------+------------------------------+
|
||||
| Field Name | Field Type | Description |
|
||||
+------------+--------------+------------------------------+
|
||||
| NAME | domain name | MUST be 0 (root domain) |
|
||||
| TYPE | u_int16_t | OPT (41) |
|
||||
| CLASS | u_int16_t | requestor's UDP payload size |
|
||||
| TTL | u_int32_t | extended RCODE and flags |
|
||||
| RDLEN | u_int16_t | length of all RDATA |
|
||||
| RDATA | octet stream | {attribute,value} pairs |
|
||||
+------------+--------------+------------------------------+
|
||||
|
||||
6.1.3. OPT Record TTL Field Use
|
||||
|
||||
The extended RCODE and flags, which OPT stores in the RR Time to Live
|
||||
(TTL) field, are structured as follows:
|
||||
|
||||
+0 (MSB) +1 (LSB)
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
0: | EXTENDED-RCODE | VERSION |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
2: | DO| Z |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
|
||||
EXTENDED-RCODE
|
||||
Forms the upper 8 bits of extended 12-bit RCODE (together with the
|
||||
4 bits defined in [RFC1035]. Note that EXTENDED-RCODE value 0
|
||||
indicates that an unextended RCODE is in use (values 0 through
|
||||
15).
|
||||
|
||||
VERSION
|
||||
Indicates the implementation level of the setter. Full
|
||||
conformance with this specification is indicated by version '0'.
|
||||
Requestors are encouraged to set this to the lowest implemented
|
||||
level capable of expressing a transaction, to minimise the
|
||||
responder and network load of discovering the greatest common
|
||||
implementation level between requestor and responder. A
|
||||
requestor's version numbering strategy MAY ideally be a run-time
|
||||
configuration option.
|
||||
If a responder does not implement the VERSION level of the
|
||||
request, then it MUST respond with RCODE=BADVERS. All responses
|
||||
MUST be limited in format to the VERSION level of the request, but
|
||||
the VERSION of each response SHOULD be the highest implementation
|
||||
level of the responder. In this way, a requestor will learn the
|
||||
implementation level of a responder as a side effect of every
|
||||
response, including error responses and including RCODE=BADVERS.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// A options resource record.
|
||||
/// </summary>
|
||||
internal class OptRecord : DnsResourceRecord
|
||||
{
|
||||
private const uint ResponseCodeMask = 0xff000000;
|
||||
private const int ResponseCodeShift = 20;
|
||||
private const uint VersionMask = 0x00ff0000;
|
||||
private const int VersionShift = 16;
|
||||
|
||||
public DnsResponseCode ResponseCodeEx
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DnsResponseCode)((InitialTimeToLive & ResponseCodeMask) >> ResponseCodeShift);
|
||||
}
|
||||
set
|
||||
{
|
||||
InitialTimeToLive &= (int)~ResponseCodeMask;
|
||||
InitialTimeToLive |= (int)(((int)value << ResponseCodeShift) & ResponseCodeMask);
|
||||
}
|
||||
}
|
||||
|
||||
public short UdpSize
|
||||
{
|
||||
get { return (short)RecordClass; }
|
||||
}
|
||||
|
||||
public byte Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((InitialTimeToLive & VersionMask) >> VersionShift);
|
||||
}
|
||||
set
|
||||
{
|
||||
InitialTimeToLive = (int)((uint)InitialTimeToLive & ~VersionMask);
|
||||
InitialTimeToLive |= (int)((value << VersionShift) & VersionMask);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDnsSecOk
|
||||
{
|
||||
get { return (InitialTimeToLive & 0x8000) != 0; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
InitialTimeToLive |= 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
InitialTimeToLive &= 0x7fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OptRecord(int size = 4096, int version = 0, int length = 0)
|
||||
: base(new ResourceRecordInfo(DnsString.RootLabel, ResourceRecordType.OPT, (QueryClass)size, version, length))
|
||||
{
|
||||
}
|
||||
|
||||
private protected override string RecordToString()
|
||||
{
|
||||
return $"OPT {RecordClass}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user