technitium 0.4.0

Typed async Rust client for the Technitium DNS Server API
Documentation
# DNS Client: Resolve Query

## Endpoint
`/api/dnsClient/resolve`

**Obsolete Path:** `/api/resolveQuery`

## Method
GET

## Description
Resolves a DNS query using the DNS client. Allows querying specific name servers, the recursive resolver, or system DNS. Optionally imports the response into an authoritative zone.

## Authentication
Required. Token must have **DnsClient: View** permission.

## Parameters

| Name | Type | Required | Conditional | Description |
|------|------|----------|-------------|-------------|
| `token` | string | Yes | No | Session token from `login` or `createToken`. |
| `node` | string | No | No | Node domain name for cluster targeting. Only usable when Clustering is initialized. Defaults to current node. |
| `server` | string | Yes | No | Name server to query. Use `recursive-resolver` for recursive resolution. Use `system-dns` to query system-configured DNS servers. |
| `domain` | string | Yes | No | The domain name to query. |
| `type` | string | Yes | No | The DNS record type to query (e.g., `A`, `AAAA`, `CNAME`, `MX`, `AXFR`, etc.). |
| `protocol` | string | No | No | DNS transport protocol. Valid values: [`Udp`, `Tcp`, `Tls`, `Https`, `Quic`]. Default: `Udp`. |
| `dnssec` | bool | No | No | Set to `true` to enable DNSSEC validation. |
| `eDnsClientSubnet` | string | No | No | Network address to use with EDNS Client Subnet option in the request. |
| `import` | bool | No | No | When `true`, imports the DNS query response into an authoritative zone on this server. Default: `false`. |

## Response Fields

The response is wrapped in `response.result` and contains a full DNS message:

| Field | Type | Description |
|-------|------|-------------|
| `Metadata.NameServer` | string | Name server that responded, with address. |
| `Metadata.Protocol` | string | Transport protocol used. |
| `Metadata.DatagramSize` | string | Size of the response datagram. |
| `Metadata.RoundTripTime` | string | Round trip time for the query. |
| `Identifier` | integer | DNS message identifier. |
| `IsResponse` | bool | Whether this is a response message. |
| `OPCODE` | string | Operation code (e.g., `StandardQuery`). |
| `AuthoritativeAnswer` | bool | Whether the response is authoritative. |
| `Truncation` | bool | Whether the response was truncated. |
| `RecursionDesired` | bool | Whether recursion was desired. |
| `RecursionAvailable` | bool | Whether recursion is available. |
| `Z` | integer | Reserved bits. |
| `AuthenticData` | bool | DNSSEC authentic data flag. |
| `CheckingDisabled` | bool | DNSSEC checking disabled flag. |
| `RCODE` | string | Response code (e.g., `NoError`, `NxDomain`). |
| `QDCOUNT` | integer | Number of questions. |
| `ANCOUNT` | integer | Number of answer records. |
| `NSCOUNT` | integer | Number of authority records. |
| `ARCOUNT` | integer | Number of additional records. |
| `Question` | array | Array of question objects with `Name`, `Type`, `Class`. |
| `Answer` | array | Array of answer records with `Name`, `Type`, `Class`, `TTL`, `RDLENGTH`, `RDATA`. |
| `Authority` | array | Array of authority records. |
| `Additional` | array | Array of additional records. |
| `rawResponses` | array | Raw response data. |

## Conditional Logic Notes

- **Import behavior**: When `import` is `true`:
  - If no zone exists for the domain, a **primary zone** is created automatically.
  - Import works only for **primary** and **forwarder** zone types.
  - When `type` is `AXFR`, the import behaves as a zone transfer: the complete zone is updated per the zone transfer response.
  - Any existing records of the given `type` will be **overwritten** when syncing.
  - Recommended to use `recursive-resolver` or actual name server address for `server` when importing.
  - Requires **Zones Modify** permission to create a zone, or **Zone Modify** permission to import into an existing zone (in addition to DnsClient: View).

## Edge Cases

- The `import` parameter requires additional permissions beyond `DnsClient: View`.
- When `type=AXFR` with `import=true`, the entire zone is replaced, not just individual records.
- The `node` parameter is silently ignored if Clustering is not initialized.
- The `protocol` parameter defaults to `Udp` when missing, which may cause truncation for large responses.