@opensecurity/zonzon-core 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/audit.d.ts +10 -0
  2. package/dist/audit.js +39 -0
  3. package/dist/cache-layer.test.d.ts +1 -0
  4. package/dist/cache-layer.test.js +205 -0
  5. package/dist/cache-multi-question.test.d.ts +1 -0
  6. package/dist/cache-multi-question.test.js +187 -0
  7. package/dist/dns-handler.d.ts +27 -0
  8. package/dist/dns-handler.js +323 -0
  9. package/dist/dns-service.d.ts +45 -0
  10. package/dist/dns-service.js +546 -0
  11. package/dist/dns-service.test.d.ts +1 -0
  12. package/dist/dns-service.test.js +306 -0
  13. package/dist/dns-wireformat.test.d.ts +1 -0
  14. package/dist/dns-wireformat.test.js +669 -0
  15. package/dist/firewall.d.ts +9 -0
  16. package/dist/firewall.js +62 -0
  17. package/dist/http-body-forwarding-integration.test.d.ts +1 -0
  18. package/dist/http-body-forwarding-integration.test.js +318 -0
  19. package/dist/http-body-forwarding.test.d.ts +1 -0
  20. package/dist/http-body-forwarding.test.js +84 -0
  21. package/dist/http-handler.d.ts +21 -0
  22. package/dist/http-handler.js +429 -0
  23. package/dist/http-proxy.d.ts +14 -0
  24. package/dist/http-proxy.js +135 -0
  25. package/dist/http-proxy.test.d.ts +1 -0
  26. package/dist/http-proxy.test.js +375 -0
  27. package/{src/index.ts → dist/index.d.ts} +1 -1
  28. package/dist/index.js +10 -0
  29. package/dist/rate-limiter.d.ts +11 -0
  30. package/dist/rate-limiter.js +33 -0
  31. package/dist/rate-limiter.test.d.ts +1 -0
  32. package/dist/rate-limiter.test.js +149 -0
  33. package/dist/schema.d.ts +12 -0
  34. package/dist/schema.js +124 -0
  35. package/dist/schema.test.d.ts +1 -0
  36. package/dist/schema.test.js +586 -0
  37. package/dist/sni-proxy.d.ts +12 -0
  38. package/dist/sni-proxy.js +141 -0
  39. package/dist/srv-record.test.d.ts +1 -0
  40. package/dist/srv-record.test.js +186 -0
  41. package/dist/tcp-connection-limit.test.d.ts +1 -0
  42. package/dist/tcp-connection-limit.test.js +89 -0
  43. package/dist/types.d.ts +145 -0
  44. package/dist/types.js +34 -0
  45. package/dist/wildcard-matching.test.d.ts +1 -0
  46. package/dist/wildcard-matching.test.js +162 -0
  47. package/package.json +4 -1
  48. package/src/audit.ts +0 -43
  49. package/src/cache-layer.test.ts +0 -236
  50. package/src/cache-multi-question.test.ts +0 -263
  51. package/src/dns-handler.ts +0 -355
  52. package/src/dns-service.test.ts +0 -371
  53. package/src/dns-service.ts +0 -655
  54. package/src/dns-wireformat.test.ts +0 -771
  55. package/src/env.d.ts +0 -1
  56. package/src/firewall.ts +0 -66
  57. package/src/http-body-forwarding-integration.test.ts +0 -357
  58. package/src/http-body-forwarding.test.ts +0 -101
  59. package/src/http-handler.ts +0 -489
  60. package/src/http-proxy.test.ts +0 -440
  61. package/src/http-proxy.ts +0 -148
  62. package/src/rate-limiter.test.ts +0 -144
  63. package/src/rate-limiter.ts +0 -50
  64. package/src/schema.test.ts +0 -685
  65. package/src/schema.ts +0 -137
  66. package/src/sni-proxy.ts +0 -164
  67. package/src/srv-record.test.ts +0 -211
  68. package/src/tcp-connection-limit.test.ts +0 -110
  69. package/src/types.ts +0 -168
  70. package/src/wildcard-matching.test.ts +0 -196
  71. package/tsconfig.json +0 -9
@@ -0,0 +1,141 @@
1
+ import * as net from "net";
2
+ import * as dns from "dns/promises";
3
+ import { firewallEngine } from "./firewall.js";
4
+ import { audit } from "./audit.js";
5
+ export class SniProxyService {
6
+ port;
7
+ config;
8
+ server = null;
9
+ activeConnections = new Set();
10
+ constructor(config, port = 443) {
11
+ this.config = config;
12
+ this.port = port;
13
+ }
14
+ extractSNI(data) {
15
+ try {
16
+ if (data.length < 5 || data[0] !== 0x16 || data[5] !== 0x01) {
17
+ return null;
18
+ }
19
+ let offset = 43;
20
+ if (offset >= data.length)
21
+ return null;
22
+ const sessionIdLength = data[offset];
23
+ offset += 1 + sessionIdLength;
24
+ if (offset >= data.length)
25
+ return null;
26
+ const cipherSuitesLength = data.readUInt16BE(offset);
27
+ offset += 2 + cipherSuitesLength;
28
+ if (offset >= data.length)
29
+ return null;
30
+ const compressionMethodsLength = data[offset];
31
+ offset += 1 + compressionMethodsLength;
32
+ if (offset >= data.length)
33
+ return null;
34
+ const extensionsLength = data.readUInt16BE(offset);
35
+ offset += 2;
36
+ const extensionsEnd = offset + extensionsLength;
37
+ while (offset < extensionsEnd && offset + 4 <= data.length) {
38
+ const extType = data.readUInt16BE(offset);
39
+ const extLength = data.readUInt16BE(offset + 2);
40
+ offset += 4;
41
+ if (extType === 0x0000) {
42
+ let sniOffset = offset;
43
+ sniOffset += 2;
44
+ const nameType = data[sniOffset];
45
+ if (nameType === 0) {
46
+ sniOffset += 1;
47
+ const nameLength = data.readUInt16BE(sniOffset);
48
+ sniOffset += 2;
49
+ return data.toString("utf8", sniOffset, sniOffset + nameLength);
50
+ }
51
+ }
52
+ offset += extLength;
53
+ }
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ return null;
59
+ }
60
+ async handleConnection(clientSocket) {
61
+ const clientIp = clientSocket.remoteAddress || "unknown";
62
+ let buffer = Buffer.alloc(0);
63
+ let isHandled = false;
64
+ clientSocket.on("data", async (chunk) => {
65
+ if (isHandled)
66
+ return;
67
+ buffer = Buffer.concat([buffer, chunk]);
68
+ if (buffer.length < 5)
69
+ return;
70
+ const recordLength = buffer.readUInt16BE(3);
71
+ if (buffer.length < 5 + recordLength)
72
+ return;
73
+ isHandled = true;
74
+ const sni = this.extractSNI(buffer);
75
+ if (!sni) {
76
+ audit.http(clientIp, "TLS", "UNKNOWN", ":443", 400, "Dropped: No SNI detected");
77
+ clientSocket.destroy();
78
+ return;
79
+ }
80
+ try {
81
+ if (firewallEngine.evaluateDomain(sni, this.config.firewall) === "DENY") {
82
+ throw new Error("Domain blocked by Firewall policy");
83
+ }
84
+ const records = await dns.resolve(sni);
85
+ const targetIps = records.filter(ip => typeof ip === "string");
86
+ if (targetIps.length === 0) {
87
+ throw new Error("NXDOMAIN on upstream resolution");
88
+ }
89
+ const targetIp = targetIps[0];
90
+ if (firewallEngine.evaluateIp(targetIp, this.config.firewall) === "DENY") {
91
+ throw new Error(`Target IP ${targetIp} blocked by Firewall policy`);
92
+ }
93
+ audit.http(clientIp, "TLS-SNI", sni, ":443", 200, `Tunneled to ${targetIp}`);
94
+ const srvSocket = net.connect(443, targetIp, () => {
95
+ srvSocket.write(buffer);
96
+ clientSocket.pipe(srvSocket);
97
+ srvSocket.pipe(clientSocket);
98
+ });
99
+ this.activeConnections.add(srvSocket);
100
+ srvSocket.on("close", () => this.activeConnections.delete(srvSocket));
101
+ srvSocket.on("error", (err) => {
102
+ audit.error(`Upstream tunnel fault on ${sni}:443 - ${err.message}`);
103
+ if (!clientSocket.destroyed)
104
+ clientSocket.destroy();
105
+ });
106
+ }
107
+ catch (err) {
108
+ audit.http(clientIp, "TLS-SNI", sni, ":443", 403, `Blocked: ${err.message}`);
109
+ clientSocket.destroy();
110
+ }
111
+ });
112
+ clientSocket.on("error", (err) => {
113
+ audit.error(`Client tunnel fault from ${clientIp} - ${err.message}`);
114
+ });
115
+ }
116
+ start() {
117
+ return new Promise((resolve, reject) => {
118
+ this.server = net.createServer((socket) => {
119
+ this.activeConnections.add(socket);
120
+ socket.on("close", () => this.activeConnections.delete(socket));
121
+ this.handleConnection(socket);
122
+ });
123
+ this.server.on("error", (err) => reject(err));
124
+ this.server.listen(this.port, "0.0.0.0", () => {
125
+ resolve();
126
+ });
127
+ });
128
+ }
129
+ async stop() {
130
+ if (this.server) {
131
+ for (const socket of this.activeConnections) {
132
+ socket.destroy();
133
+ }
134
+ this.activeConnections.clear();
135
+ await new Promise((resolve) => {
136
+ this.server.close(() => resolve());
137
+ });
138
+ this.server = null;
139
+ }
140
+ }
141
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,186 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "assert";
3
+ import { DevDnsServer } from "./dns-service.js";
4
+ import { DNS_TYPES, DNS_RCODE } from "./types.js";
5
+ function buildQuery(name, type) {
6
+ const encoder = new (class {
7
+ buf = Buffer.alloc(256);
8
+ offset = 0;
9
+ writeUint16(v) {
10
+ this.buf.writeUInt16BE(v, this.offset);
11
+ this.offset += 2;
12
+ }
13
+ writeUint8(v) {
14
+ this.buf.writeUInt8(v, this.offset);
15
+ this.offset += 1;
16
+ }
17
+ writeDomainName(nm) {
18
+ for (const label of nm.split(".")) {
19
+ if (label.length === 0)
20
+ continue;
21
+ this.writeUint8(label.length);
22
+ Buffer.from(label).copy(this.buf, this.offset);
23
+ this.offset += label.length;
24
+ }
25
+ this.writeUint8(0);
26
+ }
27
+ finish() {
28
+ return this.buf.subarray(0, this.offset);
29
+ }
30
+ })();
31
+ encoder.writeUint16(0xabcd);
32
+ encoder.writeUint16(0x0100);
33
+ encoder.writeUint16(1);
34
+ encoder.writeUint16(0);
35
+ encoder.writeUint16(0);
36
+ encoder.writeUint16(0);
37
+ encoder.writeDomainName(name);
38
+ encoder.writeUint16(type);
39
+ encoder.writeUint16(1);
40
+ return encoder.finish();
41
+ }
42
+ function parseResponseFlags(buf) {
43
+ const flags = buf.readUInt16BE(2);
44
+ const qr = (flags >> 15) & 0x1;
45
+ const rcode = flags & 0xf;
46
+ return { qr, rcode };
47
+ }
48
+ function getAnswerCount(buf) {
49
+ return buf.readUInt16BE(6);
50
+ }
51
+ describe("DevDnsServer - SRV Wire Format Encoding", () => {
52
+ let server;
53
+ it("returns correctly encoded SRV record with priority=10 weight=5 port=8080", () => {
54
+ const config = {
55
+ port: 53,
56
+ hosts: {
57
+ "my.service.loop": {
58
+ records: [
59
+ { type: "SRV", priority: 10, weight: 5, port: 8080, target: "backend.my.service.loop" },
60
+ ],
61
+ },
62
+ },
63
+ };
64
+ server = new DevDnsServer(config);
65
+ const queryBuffer = buildQuery("my.service.loop", DNS_TYPES.SRV);
66
+ const response = server.resolve(queryBuffer);
67
+ assert.ok(response.length > 0);
68
+ const { qr, rcode } = parseResponseFlags(response);
69
+ assert.strictEqual(qr, 1);
70
+ assert.strictEqual(rcode, DNS_RCODE.NOERROR);
71
+ const ancount = getAnswerCount(response);
72
+ assert.strictEqual(ancount, 1);
73
+ assert.ok(response.length > 40);
74
+ const rdlen = response.readUInt16BE(20);
75
+ assert.ok(rdlen >= 6);
76
+ });
77
+ it("returns correctly encoded SRV record with zero priority and weight", () => {
78
+ const config = {
79
+ port: 53,
80
+ hosts: {
81
+ "zero.srv.loop": {
82
+ records: [
83
+ { type: "SRV", priority: 0, weight: 0, port: 443, target: "primary.zero.srv.loop" },
84
+ ],
85
+ },
86
+ },
87
+ };
88
+ server = new DevDnsServer(config);
89
+ const response = server.resolve(buildQuery("zero.srv.loop", DNS_TYPES.SRV));
90
+ assert.ok(response.length > 0);
91
+ const ancount = getAnswerCount(response);
92
+ assert.strictEqual(ancount, 1);
93
+ });
94
+ it("returns multiple SRV records for same host (weighted load balancing)", () => {
95
+ const config = {
96
+ port: 53,
97
+ hosts: {
98
+ "lb.srv.loop": {
99
+ records: [
100
+ { type: "SRV", priority: 10, weight: 7, port: 8080, target: "server1.lb.srv.loop" },
101
+ { type: "SRV", priority: 20, weight: 3, port: 8080, target: "server2.lb.srv.loop" },
102
+ ],
103
+ },
104
+ },
105
+ };
106
+ server = new DevDnsServer(config);
107
+ const response = server.resolve(buildQuery("lb.srv.loop", DNS_TYPES.SRV));
108
+ assert.ok(response.length > 0);
109
+ const ancount = getAnswerCount(response);
110
+ assert.strictEqual(ancount, 2);
111
+ });
112
+ it("does not respond with A record type when host only has SRV records", () => {
113
+ const config = {
114
+ port: 53,
115
+ hosts: {
116
+ "only-srv.loop": {
117
+ records: [
118
+ { type: "SRV", priority: 10, weight: 5, port: 8080, target: "target.only-srv.loop" },
119
+ ],
120
+ },
121
+ },
122
+ };
123
+ server = new DevDnsServer(config);
124
+ const response = server.resolve(buildQuery("only-srv.loop", DNS_TYPES.A));
125
+ assert.ok(response.length > 0);
126
+ assert.strictEqual(getAnswerCount(response), 0);
127
+ const { rcode } = parseResponseFlags(response);
128
+ assert.strictEqual(rcode, DNS_RCODE.NOERROR);
129
+ });
130
+ it("handles SRV with maximum port value 65535", () => {
131
+ const config = {
132
+ port: 53,
133
+ hosts: {
134
+ "maxport.srv.loop": {
135
+ records: [
136
+ { type: "SRV", priority: 100, weight: 200, port: 65535, target: "max.maxport.srv.loop" },
137
+ ],
138
+ },
139
+ },
140
+ };
141
+ server = new DevDnsServer(config);
142
+ const response = server.resolve(buildQuery("maxport.srv.loop", DNS_TYPES.SRV));
143
+ assert.ok(response.length > 0);
144
+ const ancount = getAnswerCount(response);
145
+ assert.strictEqual(ancount, 1);
146
+ });
147
+ it("preserves query ID in SRV response", () => {
148
+ const config = {
149
+ port: 53,
150
+ hosts: {
151
+ "id.srv.loop": {
152
+ records: [
153
+ { type: "SRV", priority: 10, weight: 5, port: 8080, target: "target.id.srv.loop" },
154
+ ],
155
+ },
156
+ },
157
+ };
158
+ const testEncoder = new (class {
159
+ buf = Buffer.alloc(256);
160
+ offset = 0;
161
+ writeUint16(v) { this.buf.writeUInt16BE(v, this.offset); this.offset += 2; }
162
+ writeUint8(v) { this.buf.writeUInt8(v, this.offset); this.offset += 1; }
163
+ writeDomainName(nm) { for (const label of nm.split(".")) {
164
+ if (label.length === 0)
165
+ continue;
166
+ this.writeUint8(label.length);
167
+ Buffer.from(label).copy(this.buf, this.offset);
168
+ this.offset += label.length;
169
+ } this.writeUint8(0); }
170
+ finish() { return this.buf.subarray(0, this.offset); }
171
+ })();
172
+ const testId = 0xDEAD;
173
+ testEncoder.writeUint16(testId);
174
+ testEncoder.writeUint16(0x0100);
175
+ testEncoder.writeUint16(1);
176
+ testEncoder.writeUint16(0);
177
+ testEncoder.writeUint16(0);
178
+ testEncoder.writeUint16(0);
179
+ testEncoder.writeDomainName("id.srv.loop");
180
+ testEncoder.writeUint16(DNS_TYPES.SRV);
181
+ testEncoder.writeUint16(1);
182
+ server = new DevDnsServer(config);
183
+ const response = server.resolve(testEncoder.finish());
184
+ assert.strictEqual(response.readUInt16BE(0), testId);
185
+ });
186
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,89 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "assert";
3
+ import * as net from "net";
4
+ let PORT_BASE = 61500;
5
+ function nextPort() {
6
+ return PORT_BASE++;
7
+ }
8
+ describe("DnsHandler - TCP Connection Limiting", () => {
9
+ it("rejects new connections after max is reached", async () => {
10
+ const port = nextPort();
11
+ const { DnsHandler } = await import("./dns-handler.js");
12
+ const { DevDnsServer } = await import("./dns-service.js");
13
+ const config = { port, hosts: {}, maxTcpConnections: 2, tcpIdleTimeoutMs: 30000, rateLimitMaxRequests: 0 };
14
+ const dnsServer = new DevDnsServer(config);
15
+ const handler = new DnsHandler(dnsServer, config);
16
+ await handler.start();
17
+ try {
18
+ await new Promise((r) => setTimeout(r, 150));
19
+ const sockets = [];
20
+ for (let i = 0; i < 2; i++) {
21
+ const s = net.createConnection(port, "127.0.0.1", () => { });
22
+ sockets.push(s);
23
+ }
24
+ await new Promise((r) => setTimeout(r, 150));
25
+ const thirdPromise = new Promise((resolve) => {
26
+ const socket = net.createConnection(port, "127.0.0.1");
27
+ socket.on("connect", () => {
28
+ setTimeout(() => resolve(socket.destroyed), 500);
29
+ });
30
+ socket.on("error", () => resolve(true));
31
+ });
32
+ const destroyed = await thirdPromise;
33
+ assert.strictEqual(destroyed, true);
34
+ for (const s of sockets)
35
+ s.destroy();
36
+ }
37
+ finally {
38
+ await handler.stop();
39
+ }
40
+ });
41
+ it("admits connections when one closes (below max)", async () => {
42
+ const port = nextPort();
43
+ const { DnsHandler } = await import("./dns-handler.js");
44
+ const { DevDnsServer } = await import("./dns-service.js");
45
+ const config = { port, hosts: {}, maxTcpConnections: 2, tcpIdleTimeoutMs: 1000, rateLimitMaxRequests: 0 };
46
+ const dnsServer = new DevDnsServer(config);
47
+ const handler = new DnsHandler(dnsServer, config);
48
+ await handler.start();
49
+ try {
50
+ await new Promise((r) => setTimeout(r, 150));
51
+ const socket1 = net.createConnection(port, "127.0.0.1");
52
+ const socket2 = net.createConnection(port, "127.0.0.1");
53
+ await new Promise((r) => setTimeout(r, 150));
54
+ socket1.end();
55
+ await new Promise((r) => { socket1.on("close", r); });
56
+ await new Promise((r) => setTimeout(r, 200));
57
+ const thirdPromise = new Promise((resolve) => {
58
+ const socket3 = net.createConnection(port, "127.0.0.1", () => resolve(true));
59
+ socket3.on("error", () => resolve(false));
60
+ socket3.setTimeout(500);
61
+ socket3.on("timeout", () => { socket3.destroy(); resolve(false); });
62
+ });
63
+ const admitted = await thirdPromise;
64
+ assert.strictEqual(admitted, true);
65
+ }
66
+ finally {
67
+ await handler.stop();
68
+ }
69
+ });
70
+ it("closes idle connections after timeout", async () => {
71
+ const port = nextPort();
72
+ const { DnsHandler } = await import("./dns-handler.js");
73
+ const { DevDnsServer } = await import("./dns-service.js");
74
+ const config = { port, hosts: {}, maxTcpConnections: 5, tcpIdleTimeoutMs: 300, rateLimitMaxRequests: 0 };
75
+ const dnsServer = new DevDnsServer(config);
76
+ const handler = new DnsHandler(dnsServer, config);
77
+ await handler.start();
78
+ try {
79
+ await new Promise((r) => setTimeout(r, 150));
80
+ const socket = net.createConnection(port, "127.0.0.1");
81
+ await new Promise((r) => socket.on("connect", () => r()));
82
+ await new Promise((r) => setTimeout(r, 800));
83
+ assert.strictEqual(socket.destroyed, true);
84
+ }
85
+ finally {
86
+ await handler.stop();
87
+ }
88
+ });
89
+ });
@@ -0,0 +1,145 @@
1
+ export interface ARecord {
2
+ type: "A";
3
+ address: string;
4
+ }
5
+ export interface AAAARecord {
6
+ type: "AAAA";
7
+ address: string;
8
+ }
9
+ export interface CNAME {
10
+ type: "CNAME";
11
+ target: string;
12
+ }
13
+ export interface TXT {
14
+ type: "TXT";
15
+ data: string[];
16
+ }
17
+ export interface MX {
18
+ type: "MX";
19
+ priority: number;
20
+ exchange: string;
21
+ }
22
+ export interface NS {
23
+ type: "NS";
24
+ target: string;
25
+ }
26
+ export interface SRV {
27
+ type: "SRV";
28
+ priority: number;
29
+ weight: number;
30
+ port: number;
31
+ target: string;
32
+ }
33
+ export interface PTR {
34
+ type: "PTR";
35
+ target: string;
36
+ }
37
+ export type DnsRecord = ARecord | AAAARecord | CNAME | TXT | MX | NS | SRV | PTR;
38
+ export interface HttpProxyConfig {
39
+ enabled: boolean;
40
+ upstream?: string;
41
+ headers: Record<string, string>;
42
+ forwardRequestBody?: boolean;
43
+ maxRequestBodyBytes?: number;
44
+ }
45
+ export interface RedirectConfig {
46
+ enabled: boolean;
47
+ code: number;
48
+ target: string;
49
+ }
50
+ export interface HostConfig {
51
+ records: DnsRecord[];
52
+ http_proxy?: HttpProxyConfig;
53
+ redirect?: RedirectConfig;
54
+ }
55
+ export interface FirewallConfig {
56
+ defaultPolicy: "allow" | "deny";
57
+ allowlist_domains?: string[];
58
+ blocklist_domains?: string[];
59
+ allowlist_ranges?: string[];
60
+ blocklist_ranges?: string[];
61
+ allowlist_ips?: string[];
62
+ blocklist_ips?: string[];
63
+ }
64
+ export interface ControlPlaneConfig {
65
+ enabled?: boolean;
66
+ port?: number;
67
+ apiKey?: string;
68
+ }
69
+ export interface ServerConfig {
70
+ port: number;
71
+ fallbackDns?: string;
72
+ firewall?: FirewallConfig;
73
+ controlPlane?: ControlPlaneConfig;
74
+ dnsCacheMaxSize?: number;
75
+ dnsCacheTtlMs?: number;
76
+ maxTcpConnections?: number;
77
+ tcpIdleTimeoutMs?: number;
78
+ rateLimitMaxRequests?: number;
79
+ rateLimitWindowMs?: number;
80
+ hosts: Record<string, HostConfig>;
81
+ }
82
+ export interface DnsQuestion {
83
+ name: string;
84
+ type: number;
85
+ class: number;
86
+ }
87
+ export interface DnsResponseHeader {
88
+ id: number;
89
+ flags: number;
90
+ qdcount: number;
91
+ ancount: number;
92
+ nscount: number;
93
+ arcount: number;
94
+ }
95
+ export interface DnsQuestionSection {
96
+ questions: DnsQuestion[];
97
+ additional?: string;
98
+ }
99
+ export interface ProxiedRequest {
100
+ hostname: string;
101
+ originalUrl: string;
102
+ headers: Record<string, string>;
103
+ method: string;
104
+ body?: Buffer;
105
+ }
106
+ export interface ModifiedHeaders {
107
+ upstreamHeaders: Record<string, string>;
108
+ clientResponseHeaders: Record<string, string>;
109
+ }
110
+ export declare const DNS_CLASSES: {
111
+ IN: number;
112
+ };
113
+ export declare const DNS_TYPES: {
114
+ readonly A: 1;
115
+ readonly NS: 2;
116
+ readonly CNAME: 5;
117
+ readonly SOA: 6;
118
+ readonly MX: 15;
119
+ readonly TXT: 16;
120
+ readonly PTR: 12;
121
+ readonly AAAA: 28;
122
+ readonly SRV: 33;
123
+ };
124
+ export declare const DNS_OPCODE: {
125
+ QUERY: number;
126
+ IQUERY: number;
127
+ STATUS: number;
128
+ };
129
+ export declare const DNS_RCODE: {
130
+ NOERROR: number;
131
+ FORMERR: number;
132
+ SERVFAIL: number;
133
+ NXDOMAIN: number;
134
+ NOTIMP: number;
135
+ REFUSED: number;
136
+ };
137
+ export declare const RESPONSE_FLAGS: {
138
+ QR: number;
139
+ AA: number;
140
+ TC: number;
141
+ RD: number;
142
+ RA: number;
143
+ };
144
+ export declare const MAX_DNS_PACKET_SIZE = 512;
145
+ export declare const MAX_TXT_RECORD_LENGTH = 255;
package/dist/types.js ADDED
@@ -0,0 +1,34 @@
1
+ export const DNS_CLASSES = { IN: 1 };
2
+ export const DNS_TYPES = {
3
+ A: 1,
4
+ NS: 2,
5
+ CNAME: 5,
6
+ SOA: 6,
7
+ MX: 15,
8
+ TXT: 16,
9
+ PTR: 12,
10
+ AAAA: 28,
11
+ SRV: 33,
12
+ };
13
+ export const DNS_OPCODE = {
14
+ QUERY: 0,
15
+ IQUERY: 1,
16
+ STATUS: 2,
17
+ };
18
+ export const DNS_RCODE = {
19
+ NOERROR: 0,
20
+ FORMERR: 1,
21
+ SERVFAIL: 2,
22
+ NXDOMAIN: 3,
23
+ NOTIMP: 4,
24
+ REFUSED: 5,
25
+ };
26
+ export const RESPONSE_FLAGS = {
27
+ QR: (1 << 15),
28
+ AA: (1 << 10),
29
+ TC: (1 << 9),
30
+ RD: (1 << 8),
31
+ RA: (1 << 7),
32
+ };
33
+ export const MAX_DNS_PACKET_SIZE = 512;
34
+ export const MAX_TXT_RECORD_LENGTH = 255;
@@ -0,0 +1 @@
1
+ export {};