読むバイナリは、dig cloudflare.com type65
の結果返ってくるものの、RRの部分です。(参考)
; <<>> DiG 9.16.1-Ubuntu <<>> cloudflare.com type65 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47082 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;cloudflare.com. IN TYPE65 ;; ANSWER SECTION: cloudflare.com. 107 IN TYPE65 \# 79 000100000100180268330568332D32390568332D32380568332D3237 02683200040008681084E5681085E500060020260647000000000000 000000681084E5260647000000000000000000681085E5 ;; Query time: 0 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: 土 1月 15 15:52:40 JST 2022 ;; MSG SIZE rcvd: 134
読む際には、下記のバージョンのドラフトを参考にしています。
ちなみに、ある程度新しめのWiresharkだと普通に解釈してくれます。(3.6.1で確認。3.2.3にはありませんでした)
実装はおそらくこのあたり かと思います。
Wiresharkからcopy as Hex Stream すると以下のようになります。
\x00\x01\x00\x00\x01\x00\x18\x02\x68\x33\x05\x68\x33\x2d\x32\x39 \x05\x68\x33\x2d\x32\x38\x05\x68\x33\x2d\x32\x37\x02\x68\x32\x00 \x04\x00\x08\x68\x10\x84\xe5\x68\x10\x85\xe5\x00\x06\x00\x20\x26 \x06\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x10\x84\xe5\x26 \x06\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x10\x85\xe5
以下のように解釈できます。
\x00\x01 : SvcPriority 0 ではないので、ServiceMode \x00: fully-qualified Target Name. ここではroot label 以降はSvcParam のリスト \x00\x01: SvcParamKeys = ALPN \x00\x18: SrvParamValueが24バイト \x02: 長さ2のalpn-id \x68\x33: h3 \x05: 長さ5のalpn-id \x68\x33\x2d\x32\x39 : h3-29 \x05: 長さ5のalpn-id \x68\x33\x2d\x32\x38: h3-28 \x05: 長さ5のalpn-id \x68\x33\x2d\x32\x37: h3-27 \x02: 長さ2のalpn-id \x68\x32: h2 \x00\x04: SvcPramKey = ipv4hint \x00\x08: SvcParamValueの長さ=8バイト、2つのipv4アドレスが含まれる \x68\x10\x84\xe5: 1つ目のIPv4アドレス \x68\x10\x85\xe5: 2つ目のIPv4アドレス \x00\x06: SvcParamKey=ipv6hint \x00\x20: SvcParamValue=32バイト、2つのipv6アドレスが含まれる \x26\x06\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x10\x84\xe5: 1つ目のipv6アドレス \x26\x06\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x10\x85\xe5: 2つ目のipv6アドレス
SvcPriority
最初の2オクテットが、SrvPriorityを表します。0の場合は、AliasMode、それ以外の場合は、ServiceModeとなります。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-2.2-2.1
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-2.4.1-1
fully-qualified Target Name
長さがプレフィックスになっているラベルで表現されます、非圧縮のfully-qualified Target Name です。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-2.2-2.2
root labelであることは、D.2 の例から推測しました。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#appendix-D.2
厳密に見るためにRFC1035、RFC6895をたどっています。
RFC1035のnameの定義があります。
https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1
<domain> ::= <subdomain> | " " <subdomain> ::= <label> | <subdomain> "." <label> <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
それに対して、RFC6895 で以下のように言及されています。
https://datatracker.ietf.org/doc/html/rfc6895#section-3.3.2
3.3.2. Label Contents and Use The last label in each NAME is "ROOT", which is the zero-length label. By definition, the null or ROOT label cannot be used for any other NAME purpose.
ここでは長さ0の名前なので、root labelということが分かります。
'.' の場合、オーナー名がeffective TargetNameとして使われています。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-2.5.2-1
SvcParamsのリスト
残りの部分は、空でなければ、SvcParamsのリストが含まれています。リストの要素はSvcParamKey=SrvParamValue
のペアで定義されます。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-2.2-3
それぞれの要素は、SrvParamKeyを表す2オクテット、SrvParamValueの長さを表す2オクテット、SrvParamValueの値 から構成されています。
ALPN
SvcParamKeyが0x01のの場合にALPNであることは、15.3.2のIANA Service Parameter Keys (SvcParamKeys) に初期に登録されるものから読み解けます。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#name-initial-contents
リストのSrvParamValue全体の長さは、0x00, 0x18 から24バイトであることが分かります。
ALPNのSrvPramValueは、少なくとも1つ以上のapln-idを含んでいます。長さを表す1オクテットのプレフィックスと、alpn-idから構成されます。
ここの要素をそれぞれ読み解くと、h3, h3-29, h3-28, h3-27, h2 というリストであることが分かります。
ipv4hint
次のSvcParamKeyは、0x04なので、ipv4hintであることが分かります。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#name-initial-contents
ipv4hintの詳細は、https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#svcparamkeys-iphints に書かれています。
フォーマットは、ipアドレスのリストです。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#section-7.4-3
ここでは長さが8バイトなので2つのipv4アドレスを含んでいることが分かります。
ipv6hint
次のSvcParamKeyは0x06なので、ipv6hintであることが分かります。
https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html#name-initial-contents
ここでは、長さが32バイトなので、2つのipv6アドレスが含まれていることが分かります。