dnsquery / dns-packet

An abstract-encoding compliant module for encoding / decoding DNS packets
MIT License
0 stars 0 forks source link

Bad typescript definitions for 'OPT' type in additionals field #1

Open herenickname opened 2 weeks ago

herenickname commented 2 weeks ago

Example code:

import * as dnsPacket from 'npm:@dnsquery/dns-packet'

for await (const [message, remote] of socket) {
    const clientPacket = dnsPacket.decode(message)
    const clientEDNS = clientPacket.additionals[0].options
}

Decoded packet:

{
  id: 48097,
  type: "query",
  flags: 288,
  flag_qr: false,
  opcode: "QUERY",
  flag_aa: false,
  flag_tc: false,
  flag_rd: true,
  flag_ra: false,
  flag_z: false,
  flag_ad: true,
  flag_cd: false,
  rcode: "NOERROR",
  questions: [ { name: "i.instagram.com", type: "AAAA", class: "IN" } ],
  answers: [],
  authorities: [],
  additionals: [
    {
      name: ".",
      type: "OPT",
      udpPayloadSize: 4096,
      extendedRcode: 0,
      ednsVersion: 0,
      flags: 0,
      flag_do: false,
      options: [
        {
          code: 8,
          type: "CLIENT_SUBNET",
          data: [Uint8Array],
          family: 2,
          sourcePrefixLength: 128,
          scopePrefixLength: 0,
          ip: "2606:4700:4700::1111"
        }
      ]
    }
  ]
}

As you can see, the true path to the EDNS ECS is packet.additionals[].options[], but the typescript says: Property 'options' does not exist on type 'OptAnswer'.

Because the current typescript definition for the additionals field is:

export interface BaseAnswer<T, D> {
 type: T;
 name: string;
 ttl?: number | undefined;
 class?: RecordClass | undefined;
 data: D;
}

with data field, not options

herenickname commented 2 weeks ago

Found another flaw in definitions:

export interface ClientSubnetOptionData {
  code: 'CLIENT_SUBNET';
  ip: string;
  family?: 1 | 2;
  sourcePrefixLength?: number;
  scopePrefixLength?: number;
}

Here 'CLIENT_SUBNET' is in the code field, in reality it is in the type field

herenickname commented 2 weeks ago

I tried to set NXDOMAIN as rcode, but it was ignored. The problem seems to be that there is no type serialization at all in this part of the code: https://github.com/dnsquery/dns-packet/blob/main/index.mjs#L137