universal-doh 0.0.2 → 0.0.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.
@@ -1,4 +1,4 @@
1
- export declare function resolve(name: string, type: string): Promise<string>;
1
+ export declare function resolve(server: string, name: string, type: string): Promise<string>;
2
2
 
3
3
  export declare const version: string;
4
4
 
@@ -1,8 +1,8 @@
1
- function b(t) {
2
- return t.map((n) => String.fromCharCode(...n)).join(".");
1
+ function g(e) {
2
+ return e.map((n) => String.fromCharCode(...n)).join(".");
3
3
  }
4
- function M(t) {
5
- const n = t.split(".").filter((i) => i.length > 0), r = [];
4
+ function N(e) {
5
+ const n = e.split(".").filter((i) => i.length > 0), t = [];
6
6
  for (const i of n) {
7
7
  if (i.length < 1 || i.length > 63)
8
8
  throw new Error(
@@ -10,21 +10,21 @@ function M(t) {
10
10
  );
11
11
  if (i.startsWith("-") || i.endsWith("-"))
12
12
  throw new Error(`Label "${i}" cannot start or end with a hyphen`);
13
- const e = [];
14
- for (const a of i) {
15
- const c = a.charCodeAt(0);
13
+ const a = [];
14
+ for (const o of i) {
15
+ const c = o.charCodeAt(0);
16
16
  if (c >= 48 && c <= 57 || // '0'-'9'
17
17
  c >= 97 && c <= 122 || // 'a'-'z'
18
18
  c === 45)
19
- e.push(c);
19
+ a.push(c);
20
20
  else
21
- throw new Error(`Invalid character '${a}' in label "${i}"`);
21
+ throw new Error(`Invalid character '${o}' in label "${i}"`);
22
22
  }
23
- r.push(e);
23
+ t.push(a);
24
24
  }
25
- return r;
25
+ return t;
26
26
  }
27
- function z() {
27
+ function E() {
28
28
  return {
29
29
  id: 0,
30
30
  qr: 0,
@@ -45,268 +45,355 @@ function z() {
45
45
  additionalRecords: []
46
46
  };
47
47
  }
48
- function S(t) {
49
- const n = z();
50
- return n.rd = 1, n.qdcount += t.length, n.questions.push(...t), n.arcount += 1, n.additionalRecords.push({
48
+ function M(e) {
49
+ const n = E();
50
+ return n.rd = 1, n.qdcount += e.length, n.questions.push(...e), n.arcount += 1, n.additionalRecords.push({
51
51
  name: [],
52
52
  type: 41,
53
- class: 65535,
54
- // max supported payload size
55
- ttl: 0,
53
+ maxPayloadSize: 65535,
54
+ extendedRcode: 0,
55
+ version: 0,
56
+ do: 0,
57
+ z: 0,
56
58
  rdlength: 0,
57
59
  rdata: []
58
- }), n;
60
+ }), n.arcount += 1, n;
59
61
  }
60
- function T(t) {
61
- const n = new ArrayBuffer(1024), r = new DataView(n);
62
+ function T(e) {
63
+ const n = new ArrayBuffer(1024), t = new DataView(n);
62
64
  let i = 0;
63
- i = j(r, i, t);
64
- for (const e of t.questions)
65
- i = x(r, i, e);
66
- if (t.answers.length > 0 || t.authorityRecords.length > 0)
65
+ i = j(t, i, e);
66
+ for (const a of e.questions)
67
+ i = k(t, i, a);
68
+ if (e.answers.length > 0 || e.authorityRecords.length > 0)
67
69
  throw new Error("Cannot serialize answers or authority records for query");
68
- for (const e of t.additionalRecords)
69
- i = $(r, i, e);
70
- return i = v(r, i), n.slice(0, i);
70
+ for (const a of e.additionalRecords)
71
+ i = A(t, i, a);
72
+ return i = $(t, i), n.slice(0, i);
71
73
  }
72
- function N(t, n, r) {
73
- for (const i of r) {
74
- t.setUint8(n++, i.length);
75
- for (const e of i)
76
- t.setUint8(n++, e);
74
+ function S(e, n, t) {
75
+ for (const i of t) {
76
+ e.setUint8(n++, i.length);
77
+ for (const a of i)
78
+ e.setUint8(n++, a);
77
79
  }
78
- return t.setUint8(n++, 0), n;
80
+ return e.setUint8(n++, 0), n;
79
81
  }
80
- function $(t, n, r) {
81
- n = N(t, n, r.name), t.setUint16(n, r.type), n += 2, t.setUint16(n, r.class), n += 2, t.setUint32(n, r.ttl), n += 4, t.setUint16(n, r.rdlength), n += 2;
82
- for (const i of r.rdata)
83
- t.setUint8(n++, i);
82
+ function A(e, n, t) {
83
+ n = S(e, n, t.name), e.setUint16(n, t.type), n += 2, t.type === 41 ? e.setUint16(n, t.maxPayloadSize) : e.setUint16(n, t.class), n += 2;
84
+ let i;
85
+ if (t.type === 41 ? (i = t.extendedRcode << 24, i |= t.version << 16, i |= t.do << 15, i |= t.z) : i = t.ttl, e.setUint32(n, i), n += 4, e.setUint16(n, t.rdlength), n += 2, t.type === 41)
86
+ for (const a of t.rdata) {
87
+ e.setUint16(n, a.optionCode), n += 2, e.setUint16(n, a.optionLength), n += 2;
88
+ for (const o of a.optionData)
89
+ e.setUint8(n++, o);
90
+ }
91
+ else
92
+ for (const a of t.rdata)
93
+ e.setUint8(n++, a);
84
94
  return n;
85
95
  }
86
- function v(t, n) {
87
- const r = n + 4, i = Math.ceil(r / 128) * 128 - r;
88
- t.setUint16(n, 12), n += 2, t.setUint16(n, i), n += 2;
89
- for (let e = 0; e < i; e++)
90
- t.setUint8(n++, Math.floor(Math.random() * 255));
91
- return n;
96
+ function $(e, n) {
97
+ const t = n + 4, i = Math.ceil(t / 128) * 128 - t, a = Array.from(
98
+ { length: i },
99
+ () => Math.floor(Math.random() * 255)
100
+ ), o = {
101
+ name: [],
102
+ type: 41,
103
+ maxPayloadSize: 0,
104
+ extendedRcode: 0,
105
+ version: 0,
106
+ do: 0,
107
+ z: 0,
108
+ rdlength: a.length + 4,
109
+ rdata: [
110
+ { optionCode: 12, optionLength: a.length, optionData: a }
111
+ ]
112
+ };
113
+ return n = A(e, n, o), n;
92
114
  }
93
- function x(t, n, r) {
94
- return n = N(t, n, r.qname), t.setUint16(n, r.qtype), n += 2, t.setUint16(n, r.qclass), n += 2, n;
115
+ function k(e, n, t) {
116
+ return n = S(e, n, t.qname), e.setUint16(n, t.qtype), n += 2, e.setUint16(n, t.qclass), n += 2, n;
95
117
  }
96
- function j(t, n, r) {
97
- return t.setUint16(n, r.id), n += 2, t.setUint16(
118
+ function j(e, n, t) {
119
+ return e.setUint16(n, t.id), n += 2, e.setUint16(
98
120
  n,
99
- (r.qr & 1) << 15 | (r.opcode & 15) << 11 | (r.aa & 1) << 10 | (r.tc & 1) << 9 | (r.rd & 1) << 8 | (r.ra & 1) << 7 | (r.z & 7) << 4 | r.rcode & 15
100
- ), n += 2, t.setUint16(4, r.qdcount), n += 2, t.setUint16(6, r.ancount), n += 2, t.setUint16(8, r.nscount), n += 2, t.setUint16(10, r.arcount), n += 2, n;
121
+ (t.qr & 1) << 15 | (t.opcode & 15) << 11 | (t.aa & 1) << 10 | (t.tc & 1) << 9 | (t.rd & 1) << 8 | (t.ra & 1) << 7 | (t.z & 7) << 4 | t.rcode & 15
122
+ ), n += 2, e.setUint16(4, t.qdcount), n += 2, e.setUint16(6, t.ancount), n += 2, e.setUint16(8, t.nscount), n += 2, e.setUint16(10, t.arcount), n += 2, n;
101
123
  }
102
- function k(t, n = 0) {
103
- const r = new DataView(t), i = z();
104
- return n = I(r, n, i), n = F(r, n, i.qdcount, i.questions), n = q(
105
- r,
124
+ function I(e, n = 0) {
125
+ const t = new DataView(e), i = E();
126
+ if (n = w(t, n, i), n = B(t, n, i.qdcount, i.questions), n = x(
127
+ t,
106
128
  n,
107
129
  i.ancount,
108
130
  i.answers
109
- ), n = q(
110
- r,
131
+ ), n = x(
132
+ t,
111
133
  n,
112
134
  i.nscount,
113
135
  i.authorityRecords
114
- ), n = q(
115
- r,
136
+ ), n = F(
137
+ t,
116
138
  n,
117
139
  i.arcount,
118
140
  i.additionalRecords
119
- ), n !== t.byteLength && console.warn(
120
- `Unexpected end of message (offset: ${n}, length: ${t.byteLength})`
121
- ), i;
141
+ ), n !== e.byteLength)
142
+ throw new Error(
143
+ `Unexpected end of message (offset: ${n}, length: ${e.byteLength})`
144
+ );
145
+ return i;
122
146
  }
123
- function F(t, n, r, i) {
124
- for (let e = 0; e < r; e++) {
125
- const a = [];
126
- n = E(t, n, a, 0);
127
- const c = t.getUint16(n);
147
+ function B(e, n, t, i) {
148
+ for (let a = 0; a < t; a++) {
149
+ const o = [];
150
+ n = m(e, n, o, 0);
151
+ const c = e.getUint16(n);
128
152
  n += 2;
129
- const o = t.getUint16(n);
130
- n += 2, i.push({ qname: a, qtype: c, qclass: o });
153
+ const r = e.getUint16(n);
154
+ n += 2, i.push({ qname: o, qtype: c, qclass: r });
131
155
  }
132
156
  return n;
133
157
  }
134
- function q(t, n, r, i) {
135
- for (let e = 0; e < r; e++) {
136
- const a = [];
137
- n = E(t, n, a, 0);
138
- const c = t.getUint16(n);
158
+ function F(e, n, t, i) {
159
+ for (let a = 0; a < t; a++) {
160
+ const o = [];
161
+ n = m(e, n, o, 0);
162
+ const c = e.getUint16(n);
163
+ if (n += 2, c === 41) {
164
+ const r = {
165
+ name: o,
166
+ type: c,
167
+ maxPayloadSize: 0,
168
+ extendedRcode: 0,
169
+ version: 0,
170
+ do: 0,
171
+ z: 0,
172
+ rdlength: 0,
173
+ rdata: []
174
+ };
175
+ n = O(e, n, r), i.push(r);
176
+ } else {
177
+ const r = {
178
+ name: o,
179
+ type: c,
180
+ class: 0,
181
+ ttl: 0,
182
+ rdlength: 0,
183
+ rdata: []
184
+ };
185
+ n = v(e, n, r), i.push(r);
186
+ }
187
+ }
188
+ return n;
189
+ }
190
+ function O(e, n, t) {
191
+ t.maxPayloadSize = e.getUint16(n), n += 2;
192
+ const i = e.getUint32(n);
193
+ n += 4, t.extendedRcode = (i & 4278190080) >> 24, t.version = (i & 16711680) >> 16, t.do = (i & 32768) >> 15, t.z = i & 32767, t.rdlength = e.getUint16(n), n += 2;
194
+ const a = n + t.rdlength;
195
+ for (; n < a; ) {
196
+ const o = e.getUint16(n);
139
197
  n += 2;
140
- const o = t.getUint16(n);
198
+ const c = e.getUint16(n), r = {
199
+ optionCode: o,
200
+ optionLength: c,
201
+ optionData: []
202
+ };
141
203
  n += 2;
142
- const u = t.getUint32(n);
143
- n += 4;
144
- const p = t.getUint16(n);
204
+ for (let l = 0; l < r.optionLength; l++)
205
+ r.optionData.push(e.getUint8(n++));
206
+ t.rdata.push(r);
207
+ }
208
+ return n;
209
+ }
210
+ function v(e, n, t) {
211
+ t.class = e.getUint16(n), n += 2, t.ttl = e.getUint32(n), n += 4, t.rdlength = e.getUint16(n), n += 2;
212
+ for (let i = 0; i < t.rdlength; i++)
213
+ t.rdata.push(e.getUint8(n++));
214
+ return n;
215
+ }
216
+ function x(e, n, t, i) {
217
+ for (let a = 0; a < t; a++) {
218
+ const o = [];
219
+ n = m(e, n, o, 0);
220
+ const c = e.getUint16(n);
145
221
  n += 2;
146
- const g = [];
147
- for (let s = 0; s < p; s++)
148
- g.push(t.getUint8(n++));
149
- i.push({ name: a, type: c, class: o, ttl: u, rdlength: p, rdata: g });
222
+ const r = {
223
+ name: o,
224
+ type: c,
225
+ class: 0,
226
+ ttl: 0,
227
+ rdlength: 0,
228
+ rdata: []
229
+ };
230
+ n = v(e, n, r), i.push(r);
150
231
  }
151
232
  return n;
152
233
  }
153
- function E(t, n, r, i = 0) {
234
+ function m(e, n, t, i = 0) {
154
235
  if (i > 20)
155
236
  throw new Error("Too many nested labels");
156
- let e = t.getUint8(n++);
157
- for (; e !== 0; ) {
158
- const a = e >> 6;
159
- if (a === 0) {
237
+ let a = e.getUint8(n++);
238
+ for (; a !== 0; ) {
239
+ const o = a >> 6;
240
+ if (o === 0) {
160
241
  const c = [];
161
- for (let o = 0; o < e; o++)
162
- c.push(t.getUint8(n++));
163
- r.push(c), e = t.getUint8(n++);
164
- } else if (a === 3) {
165
- const c = (e & 63) << 8 | t.getUint8(n++);
166
- E(t, c, r, i + 1);
242
+ for (let r = 0; r < a; r++)
243
+ c.push(e.getUint8(n++));
244
+ t.push(c), a = e.getUint8(n++);
245
+ } else if (o === 3) {
246
+ const c = (a & 63) << 8 | e.getUint8(n++);
247
+ m(e, c, t, i + 1);
167
248
  break;
168
249
  } else
169
- throw new Error(`Invalid label type: ${a.toString(2)}`);
250
+ throw new Error(`Invalid label type: ${o.toString(2)}`);
170
251
  }
171
252
  return n;
172
253
  }
173
- function I(t, n, r) {
174
- r.id = t.getUint16(n), n += 2;
175
- const i = t.getUint16(n);
176
- return n += 2, r.qr = (i & 32768) >> 15, r.opcode = (i & 30720) >> 11, r.aa = (i & 1024) >> 10, r.tc = (i & 512) >> 9, r.rd = (i & 256) >> 8, r.ra = (i & 128) >> 7, r.z = (i & 112) >> 4, r.rcode = i & 15, r.qdcount = t.getUint16(n), n += 2, r.ancount = t.getUint16(n), n += 2, r.nscount = t.getUint16(n), n += 2, r.arcount = t.getUint16(n), n += 2, n;
254
+ function w(e, n, t) {
255
+ t.id = e.getUint16(n), n += 2;
256
+ const i = e.getUint16(n);
257
+ return n += 2, t.qr = (i & 32768) >> 15, t.opcode = (i & 30720) >> 11, t.aa = (i & 1024) >> 10, t.tc = (i & 512) >> 9, t.rd = (i & 256) >> 8, t.ra = (i & 128) >> 7, t.z = (i & 112) >> 4, t.rcode = i & 15, t.qdcount = e.getUint16(n), n += 2, t.ancount = e.getUint16(n), n += 2, t.nscount = e.getUint16(n), n += 2, t.arcount = e.getUint16(n), n += 2, n;
177
258
  }
178
- function P(t) {
179
- return _(t).split(".").map((e) => O(e) ? e : "xn--" + W(e)).join(".").toLowerCase();
259
+ function Q(e) {
260
+ return _(e).split(".").map((a) => H(a) ? a : "xn--" + X(a)).join(".").toLowerCase();
180
261
  }
181
- function _(t) {
182
- return t.replace(/[.。。]/gu, ".").replace(/ẞ/gu, "ß").normalize("NFKC").toLowerCase().replace(/[\uFE00-\uFE0F]/gu, "");
262
+ function _(e) {
263
+ return e.replace(/[.。。]/gu, ".").replace(/ẞ/gu, "ß").normalize("NFKC").toLowerCase().replace(/[\uFE00-\uFE0F]/gu, "");
183
264
  }
184
- function O(t) {
185
- return Array.from(t).every(D);
265
+ function H(e) {
266
+ return Array.from(e).every(D);
186
267
  }
187
- function D(t) {
188
- return t.charCodeAt(0) < 128;
268
+ function D(e) {
269
+ return e.charCodeAt(0) < 128;
189
270
  }
190
- const y = 36, w = 1, C = 26, Q = 38, B = 700, H = 72, K = 128;
191
- function W(t) {
192
- let n = K, r = 0, i = H;
193
- const e = [], a = Array.from(t), c = a.filter(D), o = c.length;
194
- let u = o;
195
- e.push(...c), o > 0 && e.push("-");
196
- const p = a.map((s) => s.codePointAt(0)), g = p.length;
197
- for (; u < g; ) {
198
- let s = Number.MAX_SAFE_INTEGER;
199
- for (const h of p)
200
- h >= n && h < s && (s = h);
201
- r += (s - n) * (u + 1), n = s;
202
- for (const h of p)
203
- if (h < n)
204
- r++;
205
- else if (h === n) {
206
- let U = r, m = y;
271
+ const h = 36, z = 1, q = 26, K = 38, W = 700, G = 72, J = 128;
272
+ function X(e) {
273
+ let n = J, t = 0, i = G;
274
+ const a = [], o = Array.from(e), c = o.filter(D), r = c.length;
275
+ let l = r;
276
+ a.push(...c), r > 0 && a.push("-");
277
+ const R = o.map((d) => d.codePointAt(0)), L = R.length;
278
+ for (; l < L; ) {
279
+ let d = Number.MAX_SAFE_INTEGER;
280
+ for (const p of R)
281
+ p >= n && p < d && (d = p);
282
+ t += (d - n) * (l + 1), n = d;
283
+ for (const p of R)
284
+ if (p < n)
285
+ t++;
286
+ else if (p === n) {
287
+ let y = t, U = h;
207
288
  for (; ; ) {
208
- let l;
209
- if (m <= i ? l = w : m >= i + C ? l = C : l = m - i, U < l) break;
210
- const L = l + (U - l) % (y - l);
211
- e.push(A(L)), U = d(U - l, y - l), m += y;
289
+ let s;
290
+ if (U <= i ? s = z : U >= i + q ? s = q : s = U - i, y < s) break;
291
+ const P = s + (y - s) % (h - s);
292
+ a.push(C(P)), y = u(y - s, h - s), U += h;
212
293
  }
213
- e.push(A(U)), i = G(
214
- r,
215
- u + 1,
216
- u === o
217
- ), r = 0, u++;
294
+ a.push(C(y)), i = Y(
295
+ t,
296
+ l + 1,
297
+ l === r
298
+ ), t = 0, l++;
218
299
  }
219
- r++, n++;
300
+ t++, n++;
220
301
  }
221
- return e.join("");
302
+ return a.join("");
222
303
  }
223
- function A(t) {
224
- return String.fromCharCode(t + 22 + 75 * +(t < 26));
304
+ function C(e) {
305
+ return String.fromCharCode(e + 22 + 75 * +(e < 26));
225
306
  }
226
- function d(t, n) {
227
- return Math.floor(t / n);
307
+ function u(e, n) {
308
+ return Math.floor(e / n);
228
309
  }
229
- function G(t, n, r) {
230
- r ? t = d(t, B) : t = d(t, 2), t += d(t, n);
310
+ function Y(e, n, t) {
311
+ t ? e = u(e, W) : e = u(e, 2), e += u(e, n);
231
312
  let i = 0;
232
- for (; t > d((y - w) * C, 2); )
233
- t = d(t, y - w), i += 36;
234
- return i + d(36 * t, t + Q);
313
+ for (; e > u((h - z) * q, 2); )
314
+ e = u(e, h - z), i += 36;
315
+ return i + u(36 * e, e + K);
235
316
  }
236
- const X = "0.0.2";
237
- function Y(t, n) {
238
- const r = P(t), i = S([
317
+ const V = "0.0.3";
318
+ function f(e, n, t) {
319
+ const i = Q(n), a = M([
239
320
  {
240
- qname: M(r),
241
- qtype: parseInt(n, 10),
321
+ qname: N(i),
322
+ qtype: parseInt(t, 10),
242
323
  qclass: 1
243
324
  // INTERNET
244
325
  }
245
- ]), e = T(i), a = new URL("https://1.1.1.1/dns-query");
246
- return fetch(a, {
326
+ ]), o = T(a), c = new URL(e);
327
+ return c.pathname = "/dns-query", fetch(c, {
247
328
  method: "POST",
248
329
  mode: "cors",
249
330
  headers: {
250
331
  Accept: "application/dns-message",
251
332
  "Content-Type": "application/dns-message"
252
333
  },
253
- body: e
254
- }).then((c) => {
255
- if (!c.ok)
256
- throw new Error(
257
- `Failed to fetch: ${c.status} ${c.statusText}`
258
- );
259
- return c.arrayBuffer();
260
- }).then((c) => {
261
- const o = k(c);
262
- return J(o);
263
- }).catch((c) => {
264
- throw console.error(c), c;
334
+ body: o
335
+ }).then((r) => r.ok ? r.arrayBuffer() : r.text().then((l) => {
336
+ throw new Error(`HTTP ${r.status}: ${l}`);
337
+ })).then((r) => {
338
+ const l = I(r);
339
+ return Z(l);
340
+ }).catch((r) => {
341
+ throw console.error(r), r;
265
342
  });
266
343
  }
267
- function J(t) {
344
+ function Z(e) {
268
345
  const n = {
269
- id: t.id,
270
- authoritativeAnswer: t.aa === 1,
271
- truncated: t.tc === 1,
272
- recursionAvailable: t.ra === 1,
273
- responseCode: t.rcode === 0 ? "OK" : "ERROR",
274
- questions: t.questions.map((r) => ({
275
- name: b(r.qname),
276
- type: r.qtype
346
+ id: e.id,
347
+ authoritativeAnswer: e.aa === 1,
348
+ truncated: e.tc === 1,
349
+ recursionAvailable: e.ra === 1,
350
+ responseCode: e.rcode === 0 ? "OK" : "ERROR",
351
+ questions: e.questions.map((t) => ({
352
+ name: g(t.qname),
353
+ type: t.qtype
277
354
  })),
278
- answers: t.answers.map((r) => ({
279
- name: b(r.name),
280
- type: r.type,
281
- ttl: r.ttl,
282
- value: R(r.type, r.rdata)
355
+ answers: e.answers.map((t) => ({
356
+ name: g(t.name),
357
+ type: t.type,
358
+ ttl: t.ttl,
359
+ value: b(t.type, t.rdata)
283
360
  })),
284
- authorityRecords: t.authorityRecords.map((r) => ({
285
- name: b(r.name),
286
- type: r.type,
287
- ttl: r.ttl,
288
- value: R(r.type, r.rdata)
361
+ authorityRecords: e.authorityRecords.map((t) => ({
362
+ name: g(t.name),
363
+ type: t.type,
364
+ ttl: t.ttl,
365
+ value: b(t.type, t.rdata)
289
366
  })),
290
- additionalRecords: t.additionalRecords.map((r) => ({
291
- name: b(r.name),
292
- type: r.type,
293
- ttl: r.ttl,
294
- value: R(r.type, r.rdata)
295
- }))
367
+ additionalRecords: e.additionalRecords.map((t) => t.type === 41 ? {
368
+ name: g(t.name),
369
+ type: t.type,
370
+ maxPayloadSize: t.maxPayloadSize,
371
+ extendedRcode: t.extendedRcode,
372
+ version: t.version,
373
+ do: t.do,
374
+ z: t.z,
375
+ value: t.rdata
376
+ } : {
377
+ name: g(t.name),
378
+ type: t.type,
379
+ class: t.class,
380
+ ttl: t.ttl,
381
+ value: b(t.type, t.rdata)
382
+ })
296
383
  };
297
384
  return JSON.stringify(n, null, 2);
298
385
  }
299
- function R(t, n) {
300
- switch (t) {
386
+ function b(e, n) {
387
+ switch (e) {
301
388
  case 1:
302
389
  return n.join(".");
303
390
  case 28:
304
- return n.map((r) => r.toString(16)).join(":");
391
+ return n.map((t) => t.toString(16)).join(":");
305
392
  default:
306
393
  return n;
307
394
  }
308
395
  }
309
396
  export {
310
- Y as resolve,
311
- X as version
397
+ f as resolve,
398
+ V as version
312
399
  };
@@ -1 +1 @@
1
- {"version":3,"file":"universal-doh.js","sources":["../lib/dns-message.ts","../lib/punycode.ts","../lib/index.ts"],"sourcesContent":["type RawDnsMessage = ArrayBuffer;\n\ninterface DnsMessage {\n id: number;\n // query (0), response (1)\n qr: BinaryFlag;\n /*\n 0 a standard query (QUERY)\n 1 an inverse query (IQUERY)\n 2 a server status request (STATUS)\n 3-15 reserved for future use\n */\n opcode: FourBitNumber;\n // Authoritative Answer\n aa: BinaryFlag;\n // TrunCation\n tc: BinaryFlag;\n // Recursion Desired\n rd: BinaryFlag;\n // Recursion Available\n ra: BinaryFlag;\n // reserved for future use - must be 0\n z: ThreeBitNumber;\n /*\n Response code\n 0 No error condition\n 1 Format error\n 2 Server failure\n 3 Name Error\n 4 Not Implemented\n 5 Refused\n 6-15 Reserved for future use.\n */\n rcode: FourBitNumber;\n // number of entries in the question section (0-65535)\n qdcount: number;\n // number of resource records in the answer section (0-65535)\n ancount: number;\n // number of name server resource records in the authority records section (0-65535)\n nscount: number;\n // number of resource records in the additional records section (0-65535)\n arcount: number;\n\n questions: DnsQuestion[];\n answers: DnsResourceRecord[];\n authorityRecords: DnsResourceRecord[];\n additionalRecords: DnsResourceRecord[];\n}\n\ntype Bytes = number[];\ntype Label = Bytes;\ntype DNSName = Label[];\n\ninterface DnsQuestion {\n qname: DNSName;\n // 16 bit unsigned integer\n qtype: number;\n // 16 bit unsigned integer\n qclass: number;\n}\n\ninterface DnsResourceRecord {\n name: DNSName;\n // 16 bit unsigned integer\n type: number;\n // 16 bit unsigned integer\n class: number;\n // 32 bit unsigned integer\n ttl: number;\n // 16 bit unsigned integer\n rdlength: number;\n rdata: Bytes;\n}\n\ntype BinaryFlag = 0 | 1;\ntype ThreeBitNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\ntype FourBitNumber =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15;\n\nexport function dnsNameToString(name: DNSName): string {\n return name.map((label) => String.fromCharCode(...label)).join(\".\");\n}\n\nexport function stringToDNSName(name: string): DNSName {\n // we can assume string is ascii but it may not be a valid domain name\n const labels = name.split(\".\").filter((label) => label.length > 0);\n const dnsName: DNSName = [];\n for (const label of labels) {\n if (label.length < 1 || label.length > 63) {\n throw new Error(\n `Label \"${label}\" must be between 1 and 63 characters long`,\n );\n }\n\n if (label.startsWith(\"-\") || label.endsWith(\"-\")) {\n throw new Error(`Label \"${label}\" cannot start or end with a hyphen`);\n }\n\n const bytes: Bytes = [];\n\n for (const char of label) {\n const code = char.charCodeAt(0);\n if (\n (code >= 48 && code <= 57) || // '0'-'9'\n (code >= 97 && code <= 122) || // 'a'-'z'\n code === 45 // '-'\n ) {\n bytes.push(code);\n } else {\n throw new Error(`Invalid character '${char}' in label \"${label}\"`);\n }\n }\n dnsName.push(bytes);\n }\n return dnsName;\n}\n\nfunction createDnsMessage() {\n return {\n id: 0,\n qr: 0,\n opcode: 0,\n aa: 0,\n tc: 0,\n rd: 0,\n ra: 0,\n z: 0,\n rcode: 0,\n qdcount: 0,\n ancount: 0,\n nscount: 0,\n arcount: 0,\n questions: [],\n answers: [],\n authorityRecords: [],\n additionalRecords: [],\n } as DnsMessage;\n}\n\nexport function createDnsQuery(questions: DnsQuestion[]): DnsMessage {\n const message = createDnsMessage();\n message.rd = 1;\n message.qdcount += questions.length;\n message.questions.push(...questions);\n\n // notify the server that we support EDNS0 by adding an OPT record\n message.arcount += 1;\n message.additionalRecords.push({\n name: [],\n type: 41,\n class: 0xffff, // max supported payload size\n ttl: 0,\n rdlength: 0,\n rdata: [],\n });\n\n return message;\n}\n\nexport function serializeDnsQuery(query: DnsMessage): RawDnsMessage {\n const buffer = new ArrayBuffer(1024);\n const message = new DataView(buffer);\n\n let offset = 0;\n offset = serializeHeader(message, offset, query);\n\n for (const question of query.questions) {\n offset = serializeQuestion(message, offset, question);\n }\n\n // we ignore the answers and authority records for queries,\n // but we include the additional records for EDNS0 support\n if (query.answers.length > 0 || query.authorityRecords.length > 0) {\n throw new Error(\"Cannot serialize answers or authority records for query\");\n }\n\n for (const record of query.additionalRecords) {\n offset = serializeResourceRecord(message, offset, record);\n }\n\n // add padding to the message for privacy\n offset = serializeEDNS0Padding(message, offset);\n\n return buffer.slice(0, offset);\n}\n\nfunction serializeName(message: DataView, offset: number, name: DNSName) {\n // TODO: consider implementing compression\n for (const label of name) {\n message.setUint8(offset++, label.length);\n for (const byte of label) {\n message.setUint8(offset++, byte);\n }\n }\n\n // empty label to terminate the domain name\n message.setUint8(offset++, 0);\n\n return offset;\n}\n\nfunction serializeResourceRecord(\n message: DataView,\n offset: number,\n record: DnsResourceRecord,\n) {\n offset = serializeName(message, offset, record.name);\n message.setUint16(offset, record.type);\n offset += 2;\n message.setUint16(offset, record.class);\n offset += 2;\n message.setUint32(offset, record.ttl);\n offset += 4;\n message.setUint16(offset, record.rdlength);\n offset += 2;\n for (const byte of record.rdata) {\n message.setUint8(offset++, byte);\n }\n\n return offset;\n}\n\nfunction serializeEDNS0Padding(message: DataView, offset: number) {\n // RFC 8467 - Recommended Strategy: Block-Length Padding\n\n // padding header of 4 bytes must be included\n const length = offset + 4;\n const padding = Math.ceil(length / 128) * 128 - length;\n\n // RFC 7830\n message.setUint16(offset, 12); // OPTION-CODE for EDNS0 padding\n offset += 2;\n message.setUint16(offset, padding); // OPTION-CODE for EDNS0 padding\n offset += 2;\n for (let i = 0; i < padding; i++) {\n // we do not need to generate cryptographically secure random numbers\n // simple random numbers are enough to obfuscate the message\n message.setUint8(offset++, Math.floor(Math.random() * 0xff));\n }\n\n return offset;\n}\n\nfunction serializeQuestion(\n message: DataView,\n offset: number,\n question: DnsQuestion,\n) {\n offset = serializeName(message, offset, question.qname);\n\n message.setUint16(offset, question.qtype);\n offset += 2;\n message.setUint16(offset, question.qclass);\n offset += 2;\n\n return offset;\n}\n\nfunction serializeHeader(\n message: DataView,\n offset: number,\n header: DnsMessage,\n) {\n // message id\n message.setUint16(offset, header.id);\n offset += 2;\n\n // flags\n message.setUint16(\n offset,\n ((header.qr & 0b1) << 15) |\n ((header.opcode & 0b1111) << 11) |\n ((header.aa & 0b1) << 10) |\n ((header.tc & 0b1) << 9) |\n ((header.rd & 0b1) << 8) |\n ((header.ra & 0b1) << 7) |\n ((header.z & 0b111) << 4) |\n (header.rcode & 0b1111),\n );\n offset += 2;\n\n // question records count\n message.setUint16(4, header.qdcount);\n offset += 2;\n\n // answer records count\n message.setUint16(6, header.ancount);\n offset += 2;\n\n // authority records count\n message.setUint16(8, header.nscount);\n offset += 2;\n\n // additional records count\n message.setUint16(10, header.arcount);\n offset += 2;\n\n return offset;\n}\n\nexport function parseDnsMessage(\n raw: RawDnsMessage,\n offset: number = 0,\n): DnsMessage {\n const rawView = new DataView(raw);\n const message = createDnsMessage();\n\n offset = parseHeader(rawView, offset, message);\n\n offset = parseQuestion(rawView, offset, message.qdcount, message.questions);\n\n offset = parseResourceRecords(\n rawView,\n offset,\n message.ancount,\n message.answers,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.nscount,\n message.authorityRecords,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.arcount,\n message.additionalRecords,\n );\n\n if (offset !== raw.byteLength) {\n // TODO: implement support for parsing padding and replace the warning with error\n console.warn(\n `Unexpected end of message (offset: ${offset}, length: ${raw.byteLength})`,\n );\n }\n\n return message;\n}\n\nfunction parseQuestion(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsQuestion[],\n) {\n for (let i = 0; i < number; i++) {\n const qname: DNSName = [];\n offset = parseName(rawView, offset, qname, 0);\n\n const qtype = rawView.getUint16(offset);\n offset += 2;\n const qclass = rawView.getUint16(offset);\n offset += 2;\n\n records.push({ qname, qtype, qclass });\n }\n return offset;\n}\n\nfunction parseResourceRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsResourceRecord[],\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n const class_ = rawView.getUint16(offset);\n offset += 2;\n const ttl = rawView.getUint32(offset);\n offset += 4;\n const rdlength = rawView.getUint16(offset);\n offset += 2;\n const rdata = [];\n for (let j = 0; j < rdlength; j++) {\n rdata.push(rawView.getUint8(offset++));\n }\n\n records.push({ name, type, class: class_, ttl, rdlength, rdata });\n }\n\n return offset;\n}\n\nfunction parseName(\n view: DataView,\n offset: number,\n output: DNSName,\n recursionDepth = 0,\n) {\n if (recursionDepth > 20) {\n throw new Error(\"Too many nested labels\");\n }\n\n let length = view.getUint8(offset++);\n while (length !== 0) {\n const labelType = length >> 6;\n if (labelType === 0b00) {\n // standard label\n const label = [];\n for (let i = 0; i < length; i++) {\n label.push(view.getUint8(offset++));\n }\n output.push(label);\n length = view.getUint8(offset++);\n } else if (labelType === 0b11) {\n // compressed label\n const pointer = ((length & 0b00111111) << 8) | view.getUint8(offset++);\n // ignore the offset as we returning from a \"jump\"\n parseName(view, pointer, output, recursionDepth + 1);\n break;\n } else {\n // we do not (yet) support extended label types (RFC2671)\n throw new Error(`Invalid label type: ${labelType.toString(2)}`);\n }\n }\n return offset;\n}\n\nfunction parseHeader(raw: DataView, offset: number, output: DnsMessage) {\n output.id = raw.getUint16(offset);\n offset += 2;\n\n const flags = raw.getUint16(offset);\n offset += 2;\n\n output.qr = ((flags & 0b1000000000000000) >> 15) as BinaryFlag;\n output.opcode = ((flags & 0b0111100000000000) >> 11) as FourBitNumber;\n output.aa = ((flags & 0b0000010000000000) >> 10) as BinaryFlag;\n output.tc = ((flags & 0b0000001000000000) >> 9) as BinaryFlag;\n output.rd = ((flags & 0b0000000100000000) >> 8) as BinaryFlag;\n output.ra = ((flags & 0b0000000010000000) >> 7) as BinaryFlag;\n output.z = ((flags & 0b0000000001110000) >> 4) as ThreeBitNumber;\n output.rcode = (flags & 0b0000000000001111) as FourBitNumber;\n\n output.qdcount = raw.getUint16(offset);\n offset += 2;\n\n output.ancount = raw.getUint16(offset);\n offset += 2;\n\n output.nscount = raw.getUint16(offset);\n offset += 2;\n\n output.arcount = raw.getUint16(offset);\n offset += 2;\n\n return offset;\n}\n","export function domainToAscii(domain: string) {\n const preprocessed = preprocessDomain(domain);\n const labels = preprocessed.split(\".\");\n\n const asciiLabels = labels.map((label) => {\n if (stringIsAscii(label)) {\n return label;\n } else {\n return \"xn--\" + punycodeEncode(label);\n }\n });\n\n return asciiLabels.join(\".\").toLowerCase();\n}\n\nfunction preprocessDomain(domain: string) {\n // https://unicode.org/reports/tr46/#TableDerivationStep1\n const exceptionalMapped = domain\n .replace(/[.。。]/gu, \".\")\n .replace(/ẞ/gu, \"ß\");\n\n // we normalize the input to Unicode Normalization Form KC\n const normalized = exceptionalMapped.normalize(\"NFKC\");\n\n // TODO: we deviate from the spec here to simplify the implementation\n // this may need to be revisited in the future\n\n // we should perform case folding here (NFKC_Casefold)\n // but we simplify this step to just lowercase the input instead\n const lowercased = normalized.toLowerCase();\n\n // remove all code points in the range U+FE00 to U+FE0F\n // (Unicode variation selectors) from the input\n // as they break emoji domains handling\n const filtered = lowercased.replace(/[\\uFE00-\\uFE0F]/gu, \"\");\n\n return filtered;\n}\n\nfunction stringIsAscii(str: string): boolean {\n return Array.from(str).every(charIsAscii);\n}\n\nfunction charIsAscii(char: string): boolean {\n return char.charCodeAt(0) < 128;\n}\n\nconst base = 36;\nconst tmin = 1;\nconst tmax = 26;\nconst skew = 38;\nconst damp = 700;\nconst initial_bias = 72;\nconst initial_n = 0x80;\n\nexport function punycodeEncode(str: string) {\n let n = initial_n;\n let delta = 0;\n let bias = initial_bias;\n const output: string[] = [];\n\n const inputChars = Array.from(str);\n\n // copy ascii chars to output\n const asciiChars = inputChars.filter(charIsAscii);\n const basicCodePoints = asciiChars.length;\n let handledCodePoints = basicCodePoints;\n output.push(...asciiChars);\n\n // append delimiter if we consumed any ascii chars\n if (basicCodePoints > 0) {\n output.push(\"-\");\n }\n\n const inputCodePoints = inputChars.map((char) => char.codePointAt(0)!);\n const inputLength = inputCodePoints.length;\n\n while (handledCodePoints < inputLength) {\n // Find the minimum code point >= n\n let m = Number.MAX_SAFE_INTEGER;\n for (const c of inputCodePoints) {\n if (c >= n && c < m) {\n m = c;\n }\n }\n\n delta += (m - n) * (handledCodePoints + 1);\n n = m;\n\n for (const c of inputCodePoints) {\n if (c < n) {\n delta++;\n } else if (c === n) {\n let q = delta;\n let k = base;\n\n while (true) {\n let t: number;\n if (k <= bias) {\n t = tmin;\n } else if (k >= bias + tmax) {\n t = tmax;\n } else {\n t = k - bias;\n }\n if (q < t) break;\n const code = t + ((q - t) % (base - t));\n output.push(encodeDigit(code));\n q = div(q - t, base - t);\n k += base;\n }\n\n output.push(encodeDigit(q));\n bias = adaptBias(\n delta,\n handledCodePoints + 1,\n handledCodePoints === basicCodePoints,\n );\n delta = 0;\n handledCodePoints++;\n }\n }\n\n delta++;\n n++;\n }\n\n return output.join(\"\");\n}\n\nfunction encodeDigit(d: number): string {\n return String.fromCharCode(d + 22 + 75 * Number(d < 26));\n}\n\nfunction div(n: number, d: number) {\n return Math.floor(n / d);\n}\n\nfunction adaptBias(delta: number, numPoints: number, firstTime: boolean) {\n if (firstTime) {\n delta = div(delta, damp);\n } else {\n delta = div(delta, 2);\n }\n\n delta += div(delta, numPoints);\n\n let k = 0;\n while (delta > div((base - tmin) * tmax, 2)) {\n delta = div(delta, base - tmin);\n\n k += 36;\n }\n\n return k + div((36 - 1 + 1) * delta, delta + skew);\n}\n","export const version = __LIB_VERSION__;\nimport {\n serializeDnsQuery,\n createDnsQuery,\n parseDnsMessage,\n stringToDNSName,\n dnsNameToString,\n} from \"./dns-message\";\nimport { domainToAscii } from \"./punycode\";\n\nexport function resolve(name: string, type: string) {\n const qualifiedName = domainToAscii(name);\n\n const query = createDnsQuery([\n {\n qname: stringToDNSName(qualifiedName),\n qtype: parseInt(type, 10),\n qclass: 1, // INTERNET\n },\n ]);\n\n const buffer = serializeDnsQuery(query);\n\n const url = new URL(\"https://1.1.1.1/dns-query\");\n return fetch(url, {\n method: \"POST\",\n mode: \"cors\",\n headers: {\n Accept: \"application/dns-message\",\n \"Content-Type\": \"application/dns-message\",\n },\n body: buffer,\n })\n .then((response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n })\n .then((buffer) => {\n const message = parseDnsMessage(buffer);\n return formatDnsMessage(message);\n })\n .catch((error) => {\n console.error(error);\n throw error;\n });\n}\n\nfunction formatDnsMessage(message: ReturnType<typeof parseDnsMessage>) {\n const formatted = {\n id: message.id,\n authoritativeAnswer: message.aa === 1,\n truncated: message.tc === 1,\n recursionAvailable: message.ra === 1,\n responseCode: message.rcode === 0 ? \"OK\" : \"ERROR\",\n questions: message.questions.map((question) => ({\n name: dnsNameToString(question.qname),\n type: question.qtype,\n })),\n answers: message.answers.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n authorityRecords: message.authorityRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n additionalRecords: message.additionalRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n };\n return JSON.stringify(formatted, null, 2);\n}\n\nfunction formatRData(recordType: number, rdata: number[]) {\n // TODO: this has to be implemented in the parser as the data\n // may include dns names and labels like for CNAMEs\n // or TXT (where there are labels but merged into a single string)\n switch (recordType) {\n case 1:\n return rdata.join(\".\");\n case 28:\n return rdata.map((c) => c.toString(16)).join(\":\");\n default:\n return rdata;\n }\n}\n"],"names":["dnsNameToString","name","label","stringToDNSName","labels","dnsName","bytes","char","code","createDnsMessage","createDnsQuery","questions","message","serializeDnsQuery","query","buffer","offset","serializeHeader","question","serializeQuestion","record","serializeResourceRecord","serializeEDNS0Padding","serializeName","byte","length","padding","i","header","parseDnsMessage","raw","rawView","parseHeader","parseQuestion","parseResourceRecords","number","records","qname","parseName","qtype","qclass","type","class_","ttl","rdlength","rdata","j","view","output","recursionDepth","labelType","pointer","flags","domainToAscii","domain","preprocessDomain","stringIsAscii","punycodeEncode","str","charIsAscii","base","tmin","tmax","skew","damp","initial_bias","initial_n","delta","bias","inputChars","asciiChars","basicCodePoints","handledCodePoints","inputCodePoints","inputLength","m","c","q","k","t","encodeDigit","div","adaptBias","d","n","numPoints","firstTime","version","resolve","qualifiedName","url","response","formatDnsMessage","error","formatted","formatRData","recordType"],"mappings":"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"}
1
+ {"version":3,"file":"universal-doh.js","sources":["../lib/dns-message.ts","../lib/punycode.ts","../lib/index.ts"],"sourcesContent":["type RawDnsMessage = ArrayBuffer;\n\ninterface DnsMessage {\n id: number;\n // query (0), response (1)\n qr: BinaryFlag;\n /*\n 0 a standard query (QUERY)\n 1 an inverse query (IQUERY)\n 2 a server status request (STATUS)\n 3-15 reserved for future use\n */\n opcode: FourBitNumber;\n // Authoritative Answer\n aa: BinaryFlag;\n // TrunCation\n tc: BinaryFlag;\n // Recursion Desired\n rd: BinaryFlag;\n // Recursion Available\n ra: BinaryFlag;\n // reserved for future use - must be 0\n z: ThreeBitNumber;\n /*\n Response code\n 0 No error condition\n 1 Format error\n 2 Server failure\n 3 Name Error\n 4 Not Implemented\n 5 Refused\n 6-15 Reserved for future use.\n */\n rcode: FourBitNumber;\n // number of entries in the question section (0-65535)\n qdcount: number;\n // number of resource records in the answer section (0-65535)\n ancount: number;\n // number of name server resource records in the authority records section (0-65535)\n nscount: number;\n // number of resource records in the additional records section (0-65535)\n arcount: number;\n\n questions: DnsQuestion[];\n answers: DnsResourceRecord[];\n authorityRecords: DnsResourceRecord[];\n additionalRecords: Array<DnsOptRecord | DnsResourceRecord>;\n}\n\ntype Bytes = number[];\ntype Label = Bytes;\ntype DNSName = Label[];\n\ninterface DnsQuestion {\n qname: DNSName;\n // 16 bit unsigned integer\n qtype: number;\n // 16 bit unsigned integer\n qclass: number;\n}\n\ninterface Opt {\n optionCode: number;\n optionLength: number;\n optionData: Bytes;\n}\n\nexport interface DnsOptRecord {\n name: DNSName;\n type: 41;\n // 16 bit unsigned integer\n maxPayloadSize: number;\n // TTL field is used as the extended RCODE and flags\n // https://datatracker.ietf.org/doc/html/rfc6891#section-6.1.3\n extendedRcode: number;\n version: number;\n do: BinaryFlag;\n z: number;\n // 16 bit unsigned integer\n rdlength: number;\n // RDATA field is used for EDNS0 options\n rdata: Opt[];\n}\n\nexport interface DnsResourceRecord {\n name: DNSName;\n // 16 bit unsigned integer\n type: number;\n // 16 bit unsigned integer\n class: number;\n // 32 bit unsigned integer\n ttl: number;\n // 16 bit unsigned integer\n rdlength: number;\n rdata: Bytes;\n}\n\ntype BinaryFlag = 0 | 1;\ntype ThreeBitNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\ntype FourBitNumber =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15;\n\nexport function dnsNameToString(name: DNSName): string {\n return name.map((label) => String.fromCharCode(...label)).join(\".\");\n}\n\nexport function stringToDNSName(name: string): DNSName {\n // we can assume string is ascii but it may not be a valid domain name\n const labels = name.split(\".\").filter((label) => label.length > 0);\n const dnsName: DNSName = [];\n for (const label of labels) {\n if (label.length < 1 || label.length > 63) {\n throw new Error(\n `Label \"${label}\" must be between 1 and 63 characters long`,\n );\n }\n\n if (label.startsWith(\"-\") || label.endsWith(\"-\")) {\n throw new Error(`Label \"${label}\" cannot start or end with a hyphen`);\n }\n\n const bytes: Bytes = [];\n\n for (const char of label) {\n const code = char.charCodeAt(0);\n if (\n (code >= 48 && code <= 57) || // '0'-'9'\n (code >= 97 && code <= 122) || // 'a'-'z'\n code === 45 // '-'\n ) {\n bytes.push(code);\n } else {\n throw new Error(`Invalid character '${char}' in label \"${label}\"`);\n }\n }\n dnsName.push(bytes);\n }\n return dnsName;\n}\n\nfunction createDnsMessage() {\n return {\n id: 0,\n qr: 0,\n opcode: 0,\n aa: 0,\n tc: 0,\n rd: 0,\n ra: 0,\n z: 0,\n rcode: 0,\n qdcount: 0,\n ancount: 0,\n nscount: 0,\n arcount: 0,\n questions: [],\n answers: [],\n authorityRecords: [],\n additionalRecords: [],\n } as DnsMessage;\n}\n\nexport function createDnsQuery(questions: DnsQuestion[]): DnsMessage {\n const message = createDnsMessage();\n message.rd = 1;\n message.qdcount += questions.length;\n message.questions.push(...questions);\n\n // notify the server that we support EDNS0 by adding an OPT record\n message.arcount += 1;\n message.additionalRecords.push({\n name: [],\n type: 41,\n maxPayloadSize: 0xffff,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: 0,\n rdata: [],\n } as DnsOptRecord);\n\n // leave space for EDNS0 padding\n message.arcount += 1;\n\n return message;\n}\n\nexport function serializeDnsQuery(query: DnsMessage): RawDnsMessage {\n const buffer = new ArrayBuffer(1024);\n const message = new DataView(buffer);\n\n let offset = 0;\n offset = serializeHeader(message, offset, query);\n\n for (const question of query.questions) {\n offset = serializeQuestion(message, offset, question);\n }\n\n // we ignore the answers and authority records for queries,\n // but we include the additional records for EDNS0 support\n if (query.answers.length > 0 || query.authorityRecords.length > 0) {\n throw new Error(\"Cannot serialize answers or authority records for query\");\n }\n\n for (const record of query.additionalRecords) {\n offset = serializeResourceRecord(message, offset, record);\n }\n\n // add padding to the message for privacy\n offset = serializeEDNS0Padding(message, offset);\n\n return buffer.slice(0, offset);\n}\n\nfunction serializeName(message: DataView, offset: number, name: DNSName) {\n // TODO: consider implementing compression\n for (const label of name) {\n message.setUint8(offset++, label.length);\n for (const byte of label) {\n message.setUint8(offset++, byte);\n }\n }\n\n // empty label to terminate the domain name\n message.setUint8(offset++, 0);\n\n return offset;\n}\n\nfunction serializeResourceRecord(\n message: DataView,\n offset: number,\n record: DnsResourceRecord | DnsOptRecord,\n) {\n offset = serializeName(message, offset, record.name);\n message.setUint16(offset, record.type);\n offset += 2;\n\n if (record.type === 41) {\n message.setUint16(offset, (<DnsOptRecord>record).maxPayloadSize);\n } else {\n message.setUint16(offset, (<DnsResourceRecord>record).class);\n }\n offset += 2;\n\n let ttl;\n if (record.type === 41) {\n ttl = (<DnsOptRecord>record).extendedRcode << 24;\n ttl |= (<DnsOptRecord>record).version << 16;\n ttl |= (<DnsOptRecord>record).do << 15;\n ttl |= (<DnsOptRecord>record).z;\n } else {\n ttl = (<DnsResourceRecord>record).ttl;\n }\n\n message.setUint32(offset, ttl);\n offset += 4;\n message.setUint16(offset, record.rdlength);\n offset += 2;\n\n if (record.type === 41) {\n // OPT record\n for (const opt of (<DnsOptRecord>record).rdata) {\n message.setUint16(offset, opt.optionCode);\n offset += 2;\n message.setUint16(offset, opt.optionLength);\n offset += 2;\n for (const byte of opt.optionData) {\n message.setUint8(offset++, byte);\n }\n }\n } else {\n for (const byte of (<DnsResourceRecord>record).rdata) {\n message.setUint8(offset++, byte);\n }\n }\n\n return offset;\n}\n\nfunction serializeEDNS0Padding(message: DataView, offset: number) {\n // RFC 8467 - Recommended Strategy: Block-Length Padding\n\n // padding header of 4 bytes must be included\n const length = offset + 4;\n const paddingLength = Math.ceil(length / 128) * 128 - length;\n\n const padding = Array.from({ length: paddingLength }, () =>\n Math.floor(Math.random() * 0xff),\n );\n\n // RFC 7830\n const paddingRecord: DnsOptRecord = {\n name: [],\n type: 41,\n maxPayloadSize: 0,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: padding.length + 4,\n rdata: [\n { optionCode: 12, optionLength: padding.length, optionData: padding },\n ],\n };\n offset = serializeResourceRecord(message, offset, paddingRecord);\n\n return offset;\n}\n\nfunction serializeQuestion(\n message: DataView,\n offset: number,\n question: DnsQuestion,\n) {\n offset = serializeName(message, offset, question.qname);\n\n message.setUint16(offset, question.qtype);\n offset += 2;\n message.setUint16(offset, question.qclass);\n offset += 2;\n\n return offset;\n}\n\nfunction serializeHeader(\n message: DataView,\n offset: number,\n header: DnsMessage,\n) {\n // message id\n message.setUint16(offset, header.id);\n offset += 2;\n\n // flags\n message.setUint16(\n offset,\n ((header.qr & 0b1) << 15) |\n ((header.opcode & 0b1111) << 11) |\n ((header.aa & 0b1) << 10) |\n ((header.tc & 0b1) << 9) |\n ((header.rd & 0b1) << 8) |\n ((header.ra & 0b1) << 7) |\n ((header.z & 0b111) << 4) |\n (header.rcode & 0b1111),\n );\n offset += 2;\n\n // question records count\n message.setUint16(4, header.qdcount);\n offset += 2;\n\n // answer records count\n message.setUint16(6, header.ancount);\n offset += 2;\n\n // authority records count\n message.setUint16(8, header.nscount);\n offset += 2;\n\n // additional records count\n message.setUint16(10, header.arcount);\n offset += 2;\n\n return offset;\n}\n\nexport function parseDnsMessage(\n raw: RawDnsMessage,\n offset: number = 0,\n): DnsMessage {\n const rawView = new DataView(raw);\n const message = createDnsMessage();\n\n offset = parseHeader(rawView, offset, message);\n\n offset = parseQuestion(rawView, offset, message.qdcount, message.questions);\n\n offset = parseResourceRecords(\n rawView,\n offset,\n message.ancount,\n message.answers,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.nscount,\n message.authorityRecords,\n );\n offset = parseAdditionalRecords(\n rawView,\n offset,\n message.arcount,\n message.additionalRecords,\n );\n\n if (offset !== raw.byteLength) {\n // TODO: implement support for parsing padding and replace the warning with error\n throw new Error(\n `Unexpected end of message (offset: ${offset}, length: ${raw.byteLength})`,\n );\n }\n\n return message;\n}\n\nfunction parseQuestion(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsQuestion[],\n) {\n for (let i = 0; i < number; i++) {\n const qname: DNSName = [];\n offset = parseName(rawView, offset, qname, 0);\n\n const qtype = rawView.getUint16(offset);\n offset += 2;\n const qclass = rawView.getUint16(offset);\n offset += 2;\n\n records.push({ qname, qtype, qclass });\n }\n return offset;\n}\n\nfunction parseAdditionalRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: Array<DnsResourceRecord | DnsOptRecord>,\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n\n if (type === 41) {\n const record: DnsOptRecord = {\n name,\n type,\n maxPayloadSize: 0,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseOptRecordBody(rawView, offset, record);\n\n records.push(record);\n } else {\n const record: DnsResourceRecord = {\n name,\n type,\n class: 0,\n ttl: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseResourceRecordBody(rawView, offset, record);\n\n records.push(record);\n }\n }\n\n return offset;\n}\n\nfunction parseOptRecordBody(\n rawView: DataView,\n offset: number,\n record: DnsOptRecord,\n) {\n record.maxPayloadSize = rawView.getUint16(offset);\n offset += 2;\n\n // TTL field is used as the extended RCODE and flags\n const ttl = rawView.getUint32(offset);\n offset += 4;\n\n record.extendedRcode = (ttl & 0xff000000) >> 24;\n record.version = (ttl & 0x00ff0000) >> 16;\n record.do = ((ttl & 0x00008000) >> 15) as BinaryFlag;\n record.z = ttl & 0x00007fff;\n\n record.rdlength = rawView.getUint16(offset);\n offset += 2;\n\n const rdEnd = offset + record.rdlength;\n\n while (offset < rdEnd) {\n const optionCode = rawView.getUint16(offset);\n offset += 2;\n const optionLength = rawView.getUint16(offset);\n const opt = {\n optionCode,\n optionLength,\n optionData: [],\n } as Opt;\n offset += 2;\n for (let k = 0; k < opt.optionLength; k++) {\n opt.optionData.push(rawView.getUint8(offset++));\n }\n record.rdata.push(opt);\n }\n return offset;\n}\n\nfunction parseResourceRecordBody(\n rawView: DataView,\n offset: number,\n record: DnsResourceRecord,\n) {\n record.class = rawView.getUint16(offset);\n offset += 2;\n record.ttl = rawView.getUint32(offset);\n offset += 4;\n record.rdlength = rawView.getUint16(offset);\n offset += 2;\n for (let j = 0; j < record.rdlength; j++) {\n record.rdata.push(rawView.getUint8(offset++));\n }\n return offset;\n}\n\nfunction parseResourceRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsResourceRecord[],\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n\n const record: DnsResourceRecord = {\n name,\n type,\n class: 0,\n ttl: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseResourceRecordBody(rawView, offset, record);\n\n records.push(record);\n }\n\n return offset;\n}\n\nfunction parseName(\n view: DataView,\n offset: number,\n output: DNSName,\n recursionDepth = 0,\n) {\n if (recursionDepth > 20) {\n throw new Error(\"Too many nested labels\");\n }\n\n let length = view.getUint8(offset++);\n while (length !== 0) {\n const labelType = length >> 6;\n if (labelType === 0b00) {\n // standard label\n const label = [];\n for (let i = 0; i < length; i++) {\n label.push(view.getUint8(offset++));\n }\n output.push(label);\n length = view.getUint8(offset++);\n } else if (labelType === 0b11) {\n // compressed label\n const pointer = ((length & 0b00111111) << 8) | view.getUint8(offset++);\n // ignore the offset as we returning from a \"jump\"\n parseName(view, pointer, output, recursionDepth + 1);\n break;\n } else {\n // we do not (yet) support extended label types (RFC2671)\n throw new Error(`Invalid label type: ${labelType.toString(2)}`);\n }\n }\n return offset;\n}\n\nfunction parseHeader(raw: DataView, offset: number, output: DnsMessage) {\n output.id = raw.getUint16(offset);\n offset += 2;\n\n const flags = raw.getUint16(offset);\n offset += 2;\n\n output.qr = ((flags & 0b1000000000000000) >> 15) as BinaryFlag;\n output.opcode = ((flags & 0b0111100000000000) >> 11) as FourBitNumber;\n output.aa = ((flags & 0b0000010000000000) >> 10) as BinaryFlag;\n output.tc = ((flags & 0b0000001000000000) >> 9) as BinaryFlag;\n output.rd = ((flags & 0b0000000100000000) >> 8) as BinaryFlag;\n output.ra = ((flags & 0b0000000010000000) >> 7) as BinaryFlag;\n output.z = ((flags & 0b0000000001110000) >> 4) as ThreeBitNumber;\n output.rcode = (flags & 0b0000000000001111) as FourBitNumber;\n\n output.qdcount = raw.getUint16(offset);\n offset += 2;\n\n output.ancount = raw.getUint16(offset);\n offset += 2;\n\n output.nscount = raw.getUint16(offset);\n offset += 2;\n\n output.arcount = raw.getUint16(offset);\n offset += 2;\n\n return offset;\n}\n","export function domainToAscii(domain: string) {\n const preprocessed = preprocessDomain(domain);\n const labels = preprocessed.split(\".\");\n\n const asciiLabels = labels.map((label) => {\n if (stringIsAscii(label)) {\n return label;\n } else {\n return \"xn--\" + punycodeEncode(label);\n }\n });\n\n return asciiLabels.join(\".\").toLowerCase();\n}\n\nfunction preprocessDomain(domain: string) {\n // https://unicode.org/reports/tr46/#TableDerivationStep1\n const exceptionalMapped = domain\n .replace(/[.。。]/gu, \".\")\n .replace(/ẞ/gu, \"ß\");\n\n // we normalize the input to Unicode Normalization Form KC\n const normalized = exceptionalMapped.normalize(\"NFKC\");\n\n // TODO: we deviate from the spec here to simplify the implementation\n // this may need to be revisited in the future\n\n // we should perform case folding here (NFKC_Casefold)\n // but we simplify this step to just lowercase the input instead\n const lowercased = normalized.toLowerCase();\n\n // remove all code points in the range U+FE00 to U+FE0F\n // (Unicode variation selectors) from the input\n // as they break emoji domains handling\n const filtered = lowercased.replace(/[\\uFE00-\\uFE0F]/gu, \"\");\n\n return filtered;\n}\n\nfunction stringIsAscii(str: string): boolean {\n return Array.from(str).every(charIsAscii);\n}\n\nfunction charIsAscii(char: string): boolean {\n return char.charCodeAt(0) < 128;\n}\n\nconst base = 36;\nconst tmin = 1;\nconst tmax = 26;\nconst skew = 38;\nconst damp = 700;\nconst initial_bias = 72;\nconst initial_n = 0x80;\n\nexport function punycodeEncode(str: string) {\n let n = initial_n;\n let delta = 0;\n let bias = initial_bias;\n const output: string[] = [];\n\n const inputChars = Array.from(str);\n\n // copy ascii chars to output\n const asciiChars = inputChars.filter(charIsAscii);\n const basicCodePoints = asciiChars.length;\n let handledCodePoints = basicCodePoints;\n output.push(...asciiChars);\n\n // append delimiter if we consumed any ascii chars\n if (basicCodePoints > 0) {\n output.push(\"-\");\n }\n\n const inputCodePoints = inputChars.map((char) => char.codePointAt(0)!);\n const inputLength = inputCodePoints.length;\n\n while (handledCodePoints < inputLength) {\n // Find the minimum code point >= n\n let m = Number.MAX_SAFE_INTEGER;\n for (const c of inputCodePoints) {\n if (c >= n && c < m) {\n m = c;\n }\n }\n\n delta += (m - n) * (handledCodePoints + 1);\n n = m;\n\n for (const c of inputCodePoints) {\n if (c < n) {\n delta++;\n } else if (c === n) {\n let q = delta;\n let k = base;\n\n while (true) {\n let t: number;\n if (k <= bias) {\n t = tmin;\n } else if (k >= bias + tmax) {\n t = tmax;\n } else {\n t = k - bias;\n }\n if (q < t) break;\n const code = t + ((q - t) % (base - t));\n output.push(encodeDigit(code));\n q = div(q - t, base - t);\n k += base;\n }\n\n output.push(encodeDigit(q));\n bias = adaptBias(\n delta,\n handledCodePoints + 1,\n handledCodePoints === basicCodePoints,\n );\n delta = 0;\n handledCodePoints++;\n }\n }\n\n delta++;\n n++;\n }\n\n return output.join(\"\");\n}\n\nfunction encodeDigit(d: number): string {\n return String.fromCharCode(d + 22 + 75 * Number(d < 26));\n}\n\nfunction div(n: number, d: number) {\n return Math.floor(n / d);\n}\n\nfunction adaptBias(delta: number, numPoints: number, firstTime: boolean) {\n if (firstTime) {\n delta = div(delta, damp);\n } else {\n delta = div(delta, 2);\n }\n\n delta += div(delta, numPoints);\n\n let k = 0;\n while (delta > div((base - tmin) * tmax, 2)) {\n delta = div(delta, base - tmin);\n\n k += 36;\n }\n\n return k + div((36 - 1 + 1) * delta, delta + skew);\n}\n","export const version = __LIB_VERSION__;\nimport type { DnsResourceRecord, DnsOptRecord } from \"./dns-message\";\nimport {\n serializeDnsQuery,\n createDnsQuery,\n parseDnsMessage,\n stringToDNSName,\n dnsNameToString,\n} from \"./dns-message\";\nimport { domainToAscii } from \"./punycode\";\n\nexport function resolve(server: string, name: string, type: string) {\n const qualifiedName = domainToAscii(name);\n\n const query = createDnsQuery([\n {\n qname: stringToDNSName(qualifiedName),\n qtype: parseInt(type, 10),\n qclass: 1, // INTERNET\n },\n ]);\n\n const buffer = serializeDnsQuery(query);\n\n const url = new URL(server);\n url.pathname = \"/dns-query\";\n\n return fetch(url, {\n method: \"POST\",\n mode: \"cors\",\n headers: {\n Accept: \"application/dns-message\",\n \"Content-Type\": \"application/dns-message\",\n },\n body: buffer,\n })\n .then((response) => {\n if (!response.ok) {\n return response.text().then((text) => {\n throw new Error(`HTTP ${response.status}: ${text}`);\n });\n }\n return response.arrayBuffer();\n })\n .then((buffer) => {\n const message = parseDnsMessage(buffer);\n return formatDnsMessage(message);\n })\n .catch((error) => {\n console.error(error);\n throw error;\n });\n}\n\nfunction formatDnsMessage(message: ReturnType<typeof parseDnsMessage>) {\n const formatted = {\n id: message.id,\n authoritativeAnswer: message.aa === 1,\n truncated: message.tc === 1,\n recursionAvailable: message.ra === 1,\n responseCode: message.rcode === 0 ? \"OK\" : \"ERROR\",\n questions: message.questions.map((question) => ({\n name: dnsNameToString(question.qname),\n type: question.qtype,\n })),\n answers: message.answers.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n authorityRecords: message.authorityRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n additionalRecords: message.additionalRecords.map((record) => {\n if (record.type === 41) {\n return {\n name: dnsNameToString(record.name),\n type: record.type,\n maxPayloadSize: (<DnsOptRecord>record).maxPayloadSize,\n extendedRcode: (<DnsOptRecord>record).extendedRcode,\n version: (<DnsOptRecord>record).version,\n do: (<DnsOptRecord>record).do,\n z: (<DnsOptRecord>record).z,\n value: (<DnsOptRecord>record).rdata,\n };\n } else {\n return {\n name: dnsNameToString(record.name),\n type: record.type,\n class: (<DnsResourceRecord>record).class,\n ttl: (<DnsResourceRecord>record).ttl,\n value: formatRData(record.type, (<DnsResourceRecord>record).rdata),\n };\n }\n }),\n };\n return JSON.stringify(formatted, null, 2);\n}\n\nfunction formatRData(recordType: number, rdata: number[]) {\n // TODO: this has to be implemented in the parser as the data\n // may include dns names and labels like for CNAMEs\n // or TXT (where there are labels but merged into a single string)\n switch (recordType) {\n case 1:\n return rdata.join(\".\");\n case 28:\n return rdata.map((c) => c.toString(16)).join(\":\");\n default:\n return rdata;\n }\n}\n"],"names":["dnsNameToString","name","label","stringToDNSName","labels","dnsName","bytes","char","code","createDnsMessage","createDnsQuery","questions","message","serializeDnsQuery","query","buffer","offset","serializeHeader","question","serializeQuestion","record","serializeResourceRecord","serializeEDNS0Padding","serializeName","byte","ttl","opt","length","paddingLength","padding","paddingRecord","header","parseDnsMessage","raw","rawView","parseHeader","parseQuestion","parseResourceRecords","parseAdditionalRecords","number","records","i","qname","parseName","qtype","qclass","type","parseOptRecordBody","parseResourceRecordBody","rdEnd","optionCode","optionLength","k","j","view","output","recursionDepth","labelType","pointer","flags","domainToAscii","domain","preprocessDomain","stringIsAscii","punycodeEncode","str","charIsAscii","base","tmin","tmax","skew","damp","initial_bias","initial_n","delta","bias","inputChars","asciiChars","basicCodePoints","handledCodePoints","inputCodePoints","inputLength","m","c","q","t","encodeDigit","div","adaptBias","d","n","numPoints","firstTime","version","resolve","server","qualifiedName","url","response","text","formatDnsMessage","error","formatted","formatRData","recordType","rdata"],"mappings":"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"}
@@ -1 +1 @@
1
- (function(d,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(d=typeof globalThis<"u"?globalThis:d||self,u(d["universal-doh"]={}))})(this,function(d){"use strict";function u(t){return t.map(n=>String.fromCharCode(...n)).join(".")}function v(t){const n=t.split(".").filter(i=>i.length>0),e=[];for(const i of n){if(i.length<1||i.length>63)throw new Error(`Label "${i}" must be between 1 and 63 characters long`);if(i.startsWith("-")||i.endsWith("-"))throw new Error(`Label "${i}" cannot start or end with a hyphen`);const r=[];for(const o of i){const c=o.charCodeAt(0);if(c>=48&&c<=57||c>=97&&c<=122||c===45)r.push(c);else throw new Error(`Invalid character '${o}' in label "${i}"`)}e.push(r)}return e}function z(){return{id:0,qr:0,opcode:0,aa:0,tc:0,rd:0,ra:0,z:0,rcode:0,qdcount:0,ancount:0,nscount:0,arcount:0,questions:[],answers:[],authorityRecords:[],additionalRecords:[]}}function D(t){const n=z();return n.rd=1,n.qdcount+=t.length,n.questions.push(...t),n.arcount+=1,n.additionalRecords.push({name:[],type:41,class:65535,ttl:0,rdlength:0,rdata:[]}),n}function M(t){const n=new ArrayBuffer(1024),e=new DataView(n);let i=0;i=x(e,i,t);for(const r of t.questions)i=j(e,i,r);if(t.answers.length>0||t.authorityRecords.length>0)throw new Error("Cannot serialize answers or authority records for query");for(const r of t.additionalRecords)i=L(e,i,r);return i=$(e,i),n.slice(0,i)}function N(t,n,e){for(const i of e){t.setUint8(n++,i.length);for(const r of i)t.setUint8(n++,r)}return t.setUint8(n++,0),n}function L(t,n,e){n=N(t,n,e.name),t.setUint16(n,e.type),n+=2,t.setUint16(n,e.class),n+=2,t.setUint32(n,e.ttl),n+=4,t.setUint16(n,e.rdlength),n+=2;for(const i of e.rdata)t.setUint8(n++,i);return n}function $(t,n){const e=n+4,i=Math.ceil(e/128)*128-e;t.setUint16(n,12),n+=2,t.setUint16(n,i),n+=2;for(let r=0;r<i;r++)t.setUint8(n++,Math.floor(Math.random()*255));return n}function j(t,n,e){return n=N(t,n,e.qname),t.setUint16(n,e.qtype),n+=2,t.setUint16(n,e.qclass),n+=2,n}function x(t,n,e){return t.setUint16(n,e.id),n+=2,t.setUint16(n,(e.qr&1)<<15|(e.opcode&15)<<11|(e.aa&1)<<10|(e.tc&1)<<9|(e.rd&1)<<8|(e.ra&1)<<7|(e.z&7)<<4|e.rcode&15),n+=2,t.setUint16(4,e.qdcount),n+=2,t.setUint16(6,e.ancount),n+=2,t.setUint16(8,e.nscount),n+=2,t.setUint16(10,e.arcount),n+=2,n}function P(t,n=0){const e=new DataView(t),i=z();return n=F(e,n,i),n=k(e,n,i.qdcount,i.questions),n=R(e,n,i.ancount,i.answers),n=R(e,n,i.nscount,i.authorityRecords),n=R(e,n,i.arcount,i.additionalRecords),n!==t.byteLength&&console.warn(`Unexpected end of message (offset: ${n}, length: ${t.byteLength})`),i}function k(t,n,e,i){for(let r=0;r<e;r++){const o=[];n=w(t,n,o,0);const c=t.getUint16(n);n+=2;const a=t.getUint16(n);n+=2,i.push({qname:o,qtype:c,qclass:a})}return n}function R(t,n,e,i){for(let r=0;r<e;r++){const o=[];n=w(t,n,o,0);const c=t.getUint16(n);n+=2;const a=t.getUint16(n);n+=2;const h=t.getUint32(n);n+=4;const g=t.getUint16(n);n+=2;const b=[];for(let s=0;s<g;s++)b.push(t.getUint8(n++));i.push({name:o,type:c,class:a,ttl:h,rdlength:g,rdata:b})}return n}function w(t,n,e,i=0){if(i>20)throw new Error("Too many nested labels");let r=t.getUint8(n++);for(;r!==0;){const o=r>>6;if(o===0){const c=[];for(let a=0;a<r;a++)c.push(t.getUint8(n++));e.push(c),r=t.getUint8(n++)}else if(o===3){const c=(r&63)<<8|t.getUint8(n++);w(t,c,e,i+1);break}else throw new Error(`Invalid label type: ${o.toString(2)}`)}return n}function F(t,n,e){e.id=t.getUint16(n),n+=2;const i=t.getUint16(n);return n+=2,e.qr=(i&32768)>>15,e.opcode=(i&30720)>>11,e.aa=(i&1024)>>10,e.tc=(i&512)>>9,e.rd=(i&256)>>8,e.ra=(i&128)>>7,e.z=(i&112)>>4,e.rcode=i&15,e.qdcount=t.getUint16(n),n+=2,e.ancount=t.getUint16(n),n+=2,e.nscount=t.getUint16(n),n+=2,e.arcount=t.getUint16(n),n+=2,n}function I(t){return O(t).split(".").map(r=>_(r)?r:"xn--"+W(r)).join(".").toLowerCase()}function O(t){return t.replace(/[.。。]/gu,".").replace(/ẞ/gu,"ß").normalize("NFKC").toLowerCase().replace(/[\uFE00-\uFE0F]/gu,"")}function _(t){return Array.from(t).every(S)}function S(t){return t.charCodeAt(0)<128}const y=36,C=1,E=26,Q=38,B=700,H=72,K=128;function W(t){let n=K,e=0,i=H;const r=[],o=Array.from(t),c=o.filter(S),a=c.length;let h=a;r.push(...c),a>0&&r.push("-");const g=o.map(s=>s.codePointAt(0)),b=g.length;for(;h<b;){let s=Number.MAX_SAFE_INTEGER;for(const U of g)U>=n&&U<s&&(s=U);e+=(s-n)*(h+1),n=s;for(const U of g)if(U<n)e++;else if(U===n){let m=e,q=y;for(;;){let l;if(q<=i?l=C:q>=i+E?l=E:l=q-i,m<l)break;const Z=l+(m-l)%(y-l);r.push(T(Z)),m=p(m-l,y-l),q+=y}r.push(T(m)),i=G(e,h+1,h===a),e=0,h++}e++,n++}return r.join("")}function T(t){return String.fromCharCode(t+22+75*+(t<26))}function p(t,n){return Math.floor(t/n)}function G(t,n,e){e?t=p(t,B):t=p(t,2),t+=p(t,n);let i=0;for(;t>p((y-C)*E,2);)t=p(t,y-C),i+=36;return i+p(36*t,t+Q)}const J="0.0.2";function X(t,n){const e=I(t),i=D([{qname:v(e),qtype:parseInt(n,10),qclass:1}]),r=M(i),o=new URL("https://1.1.1.1/dns-query");return fetch(o,{method:"POST",mode:"cors",headers:{Accept:"application/dns-message","Content-Type":"application/dns-message"},body:r}).then(c=>{if(!c.ok)throw new Error(`Failed to fetch: ${c.status} ${c.statusText}`);return c.arrayBuffer()}).then(c=>{const a=P(c);return Y(a)}).catch(c=>{throw console.error(c),c})}function Y(t){const n={id:t.id,authoritativeAnswer:t.aa===1,truncated:t.tc===1,recursionAvailable:t.ra===1,responseCode:t.rcode===0?"OK":"ERROR",questions:t.questions.map(e=>({name:u(e.qname),type:e.qtype})),answers:t.answers.map(e=>({name:u(e.name),type:e.type,ttl:e.ttl,value:A(e.type,e.rdata)})),authorityRecords:t.authorityRecords.map(e=>({name:u(e.name),type:e.type,ttl:e.ttl,value:A(e.type,e.rdata)})),additionalRecords:t.additionalRecords.map(e=>({name:u(e.name),type:e.type,ttl:e.ttl,value:A(e.type,e.rdata)}))};return JSON.stringify(n,null,2)}function A(t,n){switch(t){case 1:return n.join(".");case 28:return n.map(e=>e.toString(16)).join(":");default:return n}}d.resolve=X,d.version=J,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1
+ (function(d,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(d=typeof globalThis<"u"?globalThis:d||self,s(d["universal-doh"]={}))})(this,function(d){"use strict";function s(e){return e.map(n=>String.fromCharCode(...n)).join(".")}function P(e){const n=e.split(".").filter(i=>i.length>0),t=[];for(const i of n){if(i.length<1||i.length>63)throw new Error(`Label "${i}" must be between 1 and 63 characters long`);if(i.startsWith("-")||i.endsWith("-"))throw new Error(`Label "${i}" cannot start or end with a hyphen`);const a=[];for(const r of i){const c=r.charCodeAt(0);if(c>=48&&c<=57||c>=97&&c<=122||c===45)a.push(c);else throw new Error(`Invalid character '${r}' in label "${i}"`)}t.push(a)}return t}function C(){return{id:0,qr:0,opcode:0,aa:0,tc:0,rd:0,ra:0,z:0,rcode:0,qdcount:0,ancount:0,nscount:0,arcount:0,questions:[],answers:[],authorityRecords:[],additionalRecords:[]}}function N(e){const n=C();return n.rd=1,n.qdcount+=e.length,n.questions.push(...e),n.arcount+=1,n.additionalRecords.push({name:[],type:41,maxPayloadSize:65535,extendedRcode:0,version:0,do:0,z:0,rdlength:0,rdata:[]}),n.arcount+=1,n}function T(e){const n=new ArrayBuffer(1024),t=new DataView(n);let i=0;i=j(t,i,e);for(const a of e.questions)i=$(t,i,a);if(e.answers.length>0||e.authorityRecords.length>0)throw new Error("Cannot serialize answers or authority records for query");for(const a of e.additionalRecords)i=S(t,i,a);return i=M(t,i),n.slice(0,i)}function v(e,n,t){for(const i of t){e.setUint8(n++,i.length);for(const a of i)e.setUint8(n++,a)}return e.setUint8(n++,0),n}function S(e,n,t){n=v(e,n,t.name),e.setUint16(n,t.type),n+=2,t.type===41?e.setUint16(n,t.maxPayloadSize):e.setUint16(n,t.class),n+=2;let i;if(t.type===41?(i=t.extendedRcode<<24,i|=t.version<<16,i|=t.do<<15,i|=t.z):i=t.ttl,e.setUint32(n,i),n+=4,e.setUint16(n,t.rdlength),n+=2,t.type===41)for(const a of t.rdata){e.setUint16(n,a.optionCode),n+=2,e.setUint16(n,a.optionLength),n+=2;for(const r of a.optionData)e.setUint8(n++,r)}else for(const a of t.rdata)e.setUint8(n++,a);return n}function M(e,n){const t=n+4,i=Math.ceil(t/128)*128-t,a=Array.from({length:i},()=>Math.floor(Math.random()*255)),r={name:[],type:41,maxPayloadSize:0,extendedRcode:0,version:0,do:0,z:0,rdlength:a.length+4,rdata:[{optionCode:12,optionLength:a.length,optionData:a}]};return n=S(e,n,r),n}function $(e,n,t){return n=v(e,n,t.qname),e.setUint16(n,t.qtype),n+=2,e.setUint16(n,t.qclass),n+=2,n}function j(e,n,t){return e.setUint16(n,t.id),n+=2,e.setUint16(n,(t.qr&1)<<15|(t.opcode&15)<<11|(t.aa&1)<<10|(t.tc&1)<<9|(t.rd&1)<<8|(t.ra&1)<<7|(t.z&7)<<4|t.rcode&15),n+=2,e.setUint16(4,t.qdcount),n+=2,e.setUint16(6,t.ancount),n+=2,e.setUint16(8,t.nscount),n+=2,e.setUint16(10,t.arcount),n+=2,n}function k(e,n=0){const t=new DataView(e),i=C();if(n=F(t,n,i),n=I(t,n,i.qdcount,i.questions),n=A(t,n,i.ancount,i.answers),n=A(t,n,i.nscount,i.authorityRecords),n=O(t,n,i.arcount,i.additionalRecords),n!==e.byteLength)throw new Error(`Unexpected end of message (offset: ${n}, length: ${e.byteLength})`);return i}function I(e,n,t,i){for(let a=0;a<t;a++){const r=[];n=U(e,n,r,0);const c=e.getUint16(n);n+=2;const o=e.getUint16(n);n+=2,i.push({qname:r,qtype:c,qclass:o})}return n}function O(e,n,t,i){for(let a=0;a<t;a++){const r=[];n=U(e,n,r,0);const c=e.getUint16(n);if(n+=2,c===41){const o={name:r,type:c,maxPayloadSize:0,extendedRcode:0,version:0,do:0,z:0,rdlength:0,rdata:[]};n=B(e,n,o),i.push(o)}else{const o={name:r,type:c,class:0,ttl:0,rdlength:0,rdata:[]};n=E(e,n,o),i.push(o)}}return n}function B(e,n,t){t.maxPayloadSize=e.getUint16(n),n+=2;const i=e.getUint32(n);n+=4,t.extendedRcode=(i&4278190080)>>24,t.version=(i&16711680)>>16,t.do=(i&32768)>>15,t.z=i&32767,t.rdlength=e.getUint16(n),n+=2;const a=n+t.rdlength;for(;n<a;){const r=e.getUint16(n);n+=2;const c=e.getUint16(n),o={optionCode:r,optionLength:c,optionData:[]};n+=2;for(let l=0;l<o.optionLength;l++)o.optionData.push(e.getUint8(n++));t.rdata.push(o)}return n}function E(e,n,t){t.class=e.getUint16(n),n+=2,t.ttl=e.getUint32(n),n+=4,t.rdlength=e.getUint16(n),n+=2;for(let i=0;i<t.rdlength;i++)t.rdata.push(e.getUint8(n++));return n}function A(e,n,t,i){for(let a=0;a<t;a++){const r=[];n=U(e,n,r,0);const c=e.getUint16(n);n+=2;const o={name:r,type:c,class:0,ttl:0,rdlength:0,rdata:[]};n=E(e,n,o),i.push(o)}return n}function U(e,n,t,i=0){if(i>20)throw new Error("Too many nested labels");let a=e.getUint8(n++);for(;a!==0;){const r=a>>6;if(r===0){const c=[];for(let o=0;o<a;o++)c.push(e.getUint8(n++));t.push(c),a=e.getUint8(n++)}else if(r===3){const c=(a&63)<<8|e.getUint8(n++);U(e,c,t,i+1);break}else throw new Error(`Invalid label type: ${r.toString(2)}`)}return n}function F(e,n,t){t.id=e.getUint16(n),n+=2;const i=e.getUint16(n);return n+=2,t.qr=(i&32768)>>15,t.opcode=(i&30720)>>11,t.aa=(i&1024)>>10,t.tc=(i&512)>>9,t.rd=(i&256)>>8,t.ra=(i&128)>>7,t.z=(i&112)>>4,t.rcode=i&15,t.qdcount=e.getUint16(n),n+=2,t.ancount=e.getUint16(n),n+=2,t.nscount=e.getUint16(n),n+=2,t.arcount=e.getUint16(n),n+=2,n}function w(e){return Q(e).split(".").map(a=>_(a)?a:"xn--"+J(a)).join(".").toLowerCase()}function Q(e){return e.replace(/[.。。]/gu,".").replace(/ẞ/gu,"ß").normalize("NFKC").toLowerCase().replace(/[\uFE00-\uFE0F]/gu,"")}function _(e){return Array.from(e).every(D)}function D(e){return e.charCodeAt(0)<128}const h=36,R=1,z=26,H=38,K=700,W=72,G=128;function J(e){let n=G,t=0,i=W;const a=[],r=Array.from(e),c=r.filter(D),o=c.length;let l=o;a.push(...c),o>0&&a.push("-");const x=r.map(y=>y.codePointAt(0)),f=x.length;for(;l<f;){let y=Number.MAX_SAFE_INTEGER;for(const g of x)g>=n&&g<y&&(y=g);t+=(y-n)*(l+1),n=y;for(const g of x)if(g<n)t++;else if(g===n){let m=t,b=h;for(;;){let u;if(b<=i?u=R:b>=i+z?u=z:u=b-i,m<u)break;const nn=u+(m-u)%(h-u);a.push(L(nn)),m=p(m-u,h-u),b+=h}a.push(L(m)),i=X(t,l+1,l===o),t=0,l++}t++,n++}return a.join("")}function L(e){return String.fromCharCode(e+22+75*+(e<26))}function p(e,n){return Math.floor(e/n)}function X(e,n,t){t?e=p(e,K):e=p(e,2),e+=p(e,n);let i=0;for(;e>p((h-R)*z,2);)e=p(e,h-R),i+=36;return i+p(36*e,e+H)}const Y="0.0.3";function Z(e,n,t){const i=w(n),a=N([{qname:P(i),qtype:parseInt(t,10),qclass:1}]),r=T(a),c=new URL(e);return c.pathname="/dns-query",fetch(c,{method:"POST",mode:"cors",headers:{Accept:"application/dns-message","Content-Type":"application/dns-message"},body:r}).then(o=>o.ok?o.arrayBuffer():o.text().then(l=>{throw new Error(`HTTP ${o.status}: ${l}`)})).then(o=>{const l=k(o);return V(l)}).catch(o=>{throw console.error(o),o})}function V(e){const n={id:e.id,authoritativeAnswer:e.aa===1,truncated:e.tc===1,recursionAvailable:e.ra===1,responseCode:e.rcode===0?"OK":"ERROR",questions:e.questions.map(t=>({name:s(t.qname),type:t.qtype})),answers:e.answers.map(t=>({name:s(t.name),type:t.type,ttl:t.ttl,value:q(t.type,t.rdata)})),authorityRecords:e.authorityRecords.map(t=>({name:s(t.name),type:t.type,ttl:t.ttl,value:q(t.type,t.rdata)})),additionalRecords:e.additionalRecords.map(t=>t.type===41?{name:s(t.name),type:t.type,maxPayloadSize:t.maxPayloadSize,extendedRcode:t.extendedRcode,version:t.version,do:t.do,z:t.z,value:t.rdata}:{name:s(t.name),type:t.type,class:t.class,ttl:t.ttl,value:q(t.type,t.rdata)})};return JSON.stringify(n,null,2)}function q(e,n){switch(e){case 1:return n.join(".");case 28:return n.map(t=>t.toString(16)).join(":");default:return n}}d.resolve=Z,d.version=Y,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
@@ -1 +1 @@
1
- {"version":3,"file":"universal-doh.umd.cjs","sources":["../lib/dns-message.ts","../lib/punycode.ts","../lib/index.ts"],"sourcesContent":["type RawDnsMessage = ArrayBuffer;\n\ninterface DnsMessage {\n id: number;\n // query (0), response (1)\n qr: BinaryFlag;\n /*\n 0 a standard query (QUERY)\n 1 an inverse query (IQUERY)\n 2 a server status request (STATUS)\n 3-15 reserved for future use\n */\n opcode: FourBitNumber;\n // Authoritative Answer\n aa: BinaryFlag;\n // TrunCation\n tc: BinaryFlag;\n // Recursion Desired\n rd: BinaryFlag;\n // Recursion Available\n ra: BinaryFlag;\n // reserved for future use - must be 0\n z: ThreeBitNumber;\n /*\n Response code\n 0 No error condition\n 1 Format error\n 2 Server failure\n 3 Name Error\n 4 Not Implemented\n 5 Refused\n 6-15 Reserved for future use.\n */\n rcode: FourBitNumber;\n // number of entries in the question section (0-65535)\n qdcount: number;\n // number of resource records in the answer section (0-65535)\n ancount: number;\n // number of name server resource records in the authority records section (0-65535)\n nscount: number;\n // number of resource records in the additional records section (0-65535)\n arcount: number;\n\n questions: DnsQuestion[];\n answers: DnsResourceRecord[];\n authorityRecords: DnsResourceRecord[];\n additionalRecords: DnsResourceRecord[];\n}\n\ntype Bytes = number[];\ntype Label = Bytes;\ntype DNSName = Label[];\n\ninterface DnsQuestion {\n qname: DNSName;\n // 16 bit unsigned integer\n qtype: number;\n // 16 bit unsigned integer\n qclass: number;\n}\n\ninterface DnsResourceRecord {\n name: DNSName;\n // 16 bit unsigned integer\n type: number;\n // 16 bit unsigned integer\n class: number;\n // 32 bit unsigned integer\n ttl: number;\n // 16 bit unsigned integer\n rdlength: number;\n rdata: Bytes;\n}\n\ntype BinaryFlag = 0 | 1;\ntype ThreeBitNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\ntype FourBitNumber =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15;\n\nexport function dnsNameToString(name: DNSName): string {\n return name.map((label) => String.fromCharCode(...label)).join(\".\");\n}\n\nexport function stringToDNSName(name: string): DNSName {\n // we can assume string is ascii but it may not be a valid domain name\n const labels = name.split(\".\").filter((label) => label.length > 0);\n const dnsName: DNSName = [];\n for (const label of labels) {\n if (label.length < 1 || label.length > 63) {\n throw new Error(\n `Label \"${label}\" must be between 1 and 63 characters long`,\n );\n }\n\n if (label.startsWith(\"-\") || label.endsWith(\"-\")) {\n throw new Error(`Label \"${label}\" cannot start or end with a hyphen`);\n }\n\n const bytes: Bytes = [];\n\n for (const char of label) {\n const code = char.charCodeAt(0);\n if (\n (code >= 48 && code <= 57) || // '0'-'9'\n (code >= 97 && code <= 122) || // 'a'-'z'\n code === 45 // '-'\n ) {\n bytes.push(code);\n } else {\n throw new Error(`Invalid character '${char}' in label \"${label}\"`);\n }\n }\n dnsName.push(bytes);\n }\n return dnsName;\n}\n\nfunction createDnsMessage() {\n return {\n id: 0,\n qr: 0,\n opcode: 0,\n aa: 0,\n tc: 0,\n rd: 0,\n ra: 0,\n z: 0,\n rcode: 0,\n qdcount: 0,\n ancount: 0,\n nscount: 0,\n arcount: 0,\n questions: [],\n answers: [],\n authorityRecords: [],\n additionalRecords: [],\n } as DnsMessage;\n}\n\nexport function createDnsQuery(questions: DnsQuestion[]): DnsMessage {\n const message = createDnsMessage();\n message.rd = 1;\n message.qdcount += questions.length;\n message.questions.push(...questions);\n\n // notify the server that we support EDNS0 by adding an OPT record\n message.arcount += 1;\n message.additionalRecords.push({\n name: [],\n type: 41,\n class: 0xffff, // max supported payload size\n ttl: 0,\n rdlength: 0,\n rdata: [],\n });\n\n return message;\n}\n\nexport function serializeDnsQuery(query: DnsMessage): RawDnsMessage {\n const buffer = new ArrayBuffer(1024);\n const message = new DataView(buffer);\n\n let offset = 0;\n offset = serializeHeader(message, offset, query);\n\n for (const question of query.questions) {\n offset = serializeQuestion(message, offset, question);\n }\n\n // we ignore the answers and authority records for queries,\n // but we include the additional records for EDNS0 support\n if (query.answers.length > 0 || query.authorityRecords.length > 0) {\n throw new Error(\"Cannot serialize answers or authority records for query\");\n }\n\n for (const record of query.additionalRecords) {\n offset = serializeResourceRecord(message, offset, record);\n }\n\n // add padding to the message for privacy\n offset = serializeEDNS0Padding(message, offset);\n\n return buffer.slice(0, offset);\n}\n\nfunction serializeName(message: DataView, offset: number, name: DNSName) {\n // TODO: consider implementing compression\n for (const label of name) {\n message.setUint8(offset++, label.length);\n for (const byte of label) {\n message.setUint8(offset++, byte);\n }\n }\n\n // empty label to terminate the domain name\n message.setUint8(offset++, 0);\n\n return offset;\n}\n\nfunction serializeResourceRecord(\n message: DataView,\n offset: number,\n record: DnsResourceRecord,\n) {\n offset = serializeName(message, offset, record.name);\n message.setUint16(offset, record.type);\n offset += 2;\n message.setUint16(offset, record.class);\n offset += 2;\n message.setUint32(offset, record.ttl);\n offset += 4;\n message.setUint16(offset, record.rdlength);\n offset += 2;\n for (const byte of record.rdata) {\n message.setUint8(offset++, byte);\n }\n\n return offset;\n}\n\nfunction serializeEDNS0Padding(message: DataView, offset: number) {\n // RFC 8467 - Recommended Strategy: Block-Length Padding\n\n // padding header of 4 bytes must be included\n const length = offset + 4;\n const padding = Math.ceil(length / 128) * 128 - length;\n\n // RFC 7830\n message.setUint16(offset, 12); // OPTION-CODE for EDNS0 padding\n offset += 2;\n message.setUint16(offset, padding); // OPTION-CODE for EDNS0 padding\n offset += 2;\n for (let i = 0; i < padding; i++) {\n // we do not need to generate cryptographically secure random numbers\n // simple random numbers are enough to obfuscate the message\n message.setUint8(offset++, Math.floor(Math.random() * 0xff));\n }\n\n return offset;\n}\n\nfunction serializeQuestion(\n message: DataView,\n offset: number,\n question: DnsQuestion,\n) {\n offset = serializeName(message, offset, question.qname);\n\n message.setUint16(offset, question.qtype);\n offset += 2;\n message.setUint16(offset, question.qclass);\n offset += 2;\n\n return offset;\n}\n\nfunction serializeHeader(\n message: DataView,\n offset: number,\n header: DnsMessage,\n) {\n // message id\n message.setUint16(offset, header.id);\n offset += 2;\n\n // flags\n message.setUint16(\n offset,\n ((header.qr & 0b1) << 15) |\n ((header.opcode & 0b1111) << 11) |\n ((header.aa & 0b1) << 10) |\n ((header.tc & 0b1) << 9) |\n ((header.rd & 0b1) << 8) |\n ((header.ra & 0b1) << 7) |\n ((header.z & 0b111) << 4) |\n (header.rcode & 0b1111),\n );\n offset += 2;\n\n // question records count\n message.setUint16(4, header.qdcount);\n offset += 2;\n\n // answer records count\n message.setUint16(6, header.ancount);\n offset += 2;\n\n // authority records count\n message.setUint16(8, header.nscount);\n offset += 2;\n\n // additional records count\n message.setUint16(10, header.arcount);\n offset += 2;\n\n return offset;\n}\n\nexport function parseDnsMessage(\n raw: RawDnsMessage,\n offset: number = 0,\n): DnsMessage {\n const rawView = new DataView(raw);\n const message = createDnsMessage();\n\n offset = parseHeader(rawView, offset, message);\n\n offset = parseQuestion(rawView, offset, message.qdcount, message.questions);\n\n offset = parseResourceRecords(\n rawView,\n offset,\n message.ancount,\n message.answers,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.nscount,\n message.authorityRecords,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.arcount,\n message.additionalRecords,\n );\n\n if (offset !== raw.byteLength) {\n // TODO: implement support for parsing padding and replace the warning with error\n console.warn(\n `Unexpected end of message (offset: ${offset}, length: ${raw.byteLength})`,\n );\n }\n\n return message;\n}\n\nfunction parseQuestion(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsQuestion[],\n) {\n for (let i = 0; i < number; i++) {\n const qname: DNSName = [];\n offset = parseName(rawView, offset, qname, 0);\n\n const qtype = rawView.getUint16(offset);\n offset += 2;\n const qclass = rawView.getUint16(offset);\n offset += 2;\n\n records.push({ qname, qtype, qclass });\n }\n return offset;\n}\n\nfunction parseResourceRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsResourceRecord[],\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n const class_ = rawView.getUint16(offset);\n offset += 2;\n const ttl = rawView.getUint32(offset);\n offset += 4;\n const rdlength = rawView.getUint16(offset);\n offset += 2;\n const rdata = [];\n for (let j = 0; j < rdlength; j++) {\n rdata.push(rawView.getUint8(offset++));\n }\n\n records.push({ name, type, class: class_, ttl, rdlength, rdata });\n }\n\n return offset;\n}\n\nfunction parseName(\n view: DataView,\n offset: number,\n output: DNSName,\n recursionDepth = 0,\n) {\n if (recursionDepth > 20) {\n throw new Error(\"Too many nested labels\");\n }\n\n let length = view.getUint8(offset++);\n while (length !== 0) {\n const labelType = length >> 6;\n if (labelType === 0b00) {\n // standard label\n const label = [];\n for (let i = 0; i < length; i++) {\n label.push(view.getUint8(offset++));\n }\n output.push(label);\n length = view.getUint8(offset++);\n } else if (labelType === 0b11) {\n // compressed label\n const pointer = ((length & 0b00111111) << 8) | view.getUint8(offset++);\n // ignore the offset as we returning from a \"jump\"\n parseName(view, pointer, output, recursionDepth + 1);\n break;\n } else {\n // we do not (yet) support extended label types (RFC2671)\n throw new Error(`Invalid label type: ${labelType.toString(2)}`);\n }\n }\n return offset;\n}\n\nfunction parseHeader(raw: DataView, offset: number, output: DnsMessage) {\n output.id = raw.getUint16(offset);\n offset += 2;\n\n const flags = raw.getUint16(offset);\n offset += 2;\n\n output.qr = ((flags & 0b1000000000000000) >> 15) as BinaryFlag;\n output.opcode = ((flags & 0b0111100000000000) >> 11) as FourBitNumber;\n output.aa = ((flags & 0b0000010000000000) >> 10) as BinaryFlag;\n output.tc = ((flags & 0b0000001000000000) >> 9) as BinaryFlag;\n output.rd = ((flags & 0b0000000100000000) >> 8) as BinaryFlag;\n output.ra = ((flags & 0b0000000010000000) >> 7) as BinaryFlag;\n output.z = ((flags & 0b0000000001110000) >> 4) as ThreeBitNumber;\n output.rcode = (flags & 0b0000000000001111) as FourBitNumber;\n\n output.qdcount = raw.getUint16(offset);\n offset += 2;\n\n output.ancount = raw.getUint16(offset);\n offset += 2;\n\n output.nscount = raw.getUint16(offset);\n offset += 2;\n\n output.arcount = raw.getUint16(offset);\n offset += 2;\n\n return offset;\n}\n","export function domainToAscii(domain: string) {\n const preprocessed = preprocessDomain(domain);\n const labels = preprocessed.split(\".\");\n\n const asciiLabels = labels.map((label) => {\n if (stringIsAscii(label)) {\n return label;\n } else {\n return \"xn--\" + punycodeEncode(label);\n }\n });\n\n return asciiLabels.join(\".\").toLowerCase();\n}\n\nfunction preprocessDomain(domain: string) {\n // https://unicode.org/reports/tr46/#TableDerivationStep1\n const exceptionalMapped = domain\n .replace(/[.。。]/gu, \".\")\n .replace(/ẞ/gu, \"ß\");\n\n // we normalize the input to Unicode Normalization Form KC\n const normalized = exceptionalMapped.normalize(\"NFKC\");\n\n // TODO: we deviate from the spec here to simplify the implementation\n // this may need to be revisited in the future\n\n // we should perform case folding here (NFKC_Casefold)\n // but we simplify this step to just lowercase the input instead\n const lowercased = normalized.toLowerCase();\n\n // remove all code points in the range U+FE00 to U+FE0F\n // (Unicode variation selectors) from the input\n // as they break emoji domains handling\n const filtered = lowercased.replace(/[\\uFE00-\\uFE0F]/gu, \"\");\n\n return filtered;\n}\n\nfunction stringIsAscii(str: string): boolean {\n return Array.from(str).every(charIsAscii);\n}\n\nfunction charIsAscii(char: string): boolean {\n return char.charCodeAt(0) < 128;\n}\n\nconst base = 36;\nconst tmin = 1;\nconst tmax = 26;\nconst skew = 38;\nconst damp = 700;\nconst initial_bias = 72;\nconst initial_n = 0x80;\n\nexport function punycodeEncode(str: string) {\n let n = initial_n;\n let delta = 0;\n let bias = initial_bias;\n const output: string[] = [];\n\n const inputChars = Array.from(str);\n\n // copy ascii chars to output\n const asciiChars = inputChars.filter(charIsAscii);\n const basicCodePoints = asciiChars.length;\n let handledCodePoints = basicCodePoints;\n output.push(...asciiChars);\n\n // append delimiter if we consumed any ascii chars\n if (basicCodePoints > 0) {\n output.push(\"-\");\n }\n\n const inputCodePoints = inputChars.map((char) => char.codePointAt(0)!);\n const inputLength = inputCodePoints.length;\n\n while (handledCodePoints < inputLength) {\n // Find the minimum code point >= n\n let m = Number.MAX_SAFE_INTEGER;\n for (const c of inputCodePoints) {\n if (c >= n && c < m) {\n m = c;\n }\n }\n\n delta += (m - n) * (handledCodePoints + 1);\n n = m;\n\n for (const c of inputCodePoints) {\n if (c < n) {\n delta++;\n } else if (c === n) {\n let q = delta;\n let k = base;\n\n while (true) {\n let t: number;\n if (k <= bias) {\n t = tmin;\n } else if (k >= bias + tmax) {\n t = tmax;\n } else {\n t = k - bias;\n }\n if (q < t) break;\n const code = t + ((q - t) % (base - t));\n output.push(encodeDigit(code));\n q = div(q - t, base - t);\n k += base;\n }\n\n output.push(encodeDigit(q));\n bias = adaptBias(\n delta,\n handledCodePoints + 1,\n handledCodePoints === basicCodePoints,\n );\n delta = 0;\n handledCodePoints++;\n }\n }\n\n delta++;\n n++;\n }\n\n return output.join(\"\");\n}\n\nfunction encodeDigit(d: number): string {\n return String.fromCharCode(d + 22 + 75 * Number(d < 26));\n}\n\nfunction div(n: number, d: number) {\n return Math.floor(n / d);\n}\n\nfunction adaptBias(delta: number, numPoints: number, firstTime: boolean) {\n if (firstTime) {\n delta = div(delta, damp);\n } else {\n delta = div(delta, 2);\n }\n\n delta += div(delta, numPoints);\n\n let k = 0;\n while (delta > div((base - tmin) * tmax, 2)) {\n delta = div(delta, base - tmin);\n\n k += 36;\n }\n\n return k + div((36 - 1 + 1) * delta, delta + skew);\n}\n","export const version = __LIB_VERSION__;\nimport {\n serializeDnsQuery,\n createDnsQuery,\n parseDnsMessage,\n stringToDNSName,\n dnsNameToString,\n} from \"./dns-message\";\nimport { domainToAscii } from \"./punycode\";\n\nexport function resolve(name: string, type: string) {\n const qualifiedName = domainToAscii(name);\n\n const query = createDnsQuery([\n {\n qname: stringToDNSName(qualifiedName),\n qtype: parseInt(type, 10),\n qclass: 1, // INTERNET\n },\n ]);\n\n const buffer = serializeDnsQuery(query);\n\n const url = new URL(\"https://1.1.1.1/dns-query\");\n return fetch(url, {\n method: \"POST\",\n mode: \"cors\",\n headers: {\n Accept: \"application/dns-message\",\n \"Content-Type\": \"application/dns-message\",\n },\n body: buffer,\n })\n .then((response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch: ${response.status} ${response.statusText}`,\n );\n }\n return response.arrayBuffer();\n })\n .then((buffer) => {\n const message = parseDnsMessage(buffer);\n return formatDnsMessage(message);\n })\n .catch((error) => {\n console.error(error);\n throw error;\n });\n}\n\nfunction formatDnsMessage(message: ReturnType<typeof parseDnsMessage>) {\n const formatted = {\n id: message.id,\n authoritativeAnswer: message.aa === 1,\n truncated: message.tc === 1,\n recursionAvailable: message.ra === 1,\n responseCode: message.rcode === 0 ? \"OK\" : \"ERROR\",\n questions: message.questions.map((question) => ({\n name: dnsNameToString(question.qname),\n type: question.qtype,\n })),\n answers: message.answers.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n authorityRecords: message.authorityRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n additionalRecords: message.additionalRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n };\n return JSON.stringify(formatted, null, 2);\n}\n\nfunction formatRData(recordType: number, rdata: number[]) {\n // TODO: this has to be implemented in the parser as the data\n // may include dns names and labels like for CNAMEs\n // or TXT (where there are labels but merged into a single string)\n switch (recordType) {\n case 1:\n return rdata.join(\".\");\n case 28:\n return rdata.map((c) => c.toString(16)).join(\":\");\n default:\n return rdata;\n }\n}\n"],"names":["dnsNameToString","name","label","stringToDNSName","labels","dnsName","bytes","char","code","createDnsMessage","createDnsQuery","questions","message","serializeDnsQuery","query","buffer","offset","serializeHeader","question","serializeQuestion","record","serializeResourceRecord","serializeEDNS0Padding","serializeName","byte","length","padding","i","header","parseDnsMessage","raw","rawView","parseHeader","parseQuestion","parseResourceRecords","number","records","qname","parseName","qtype","qclass","type","class_","ttl","rdlength","rdata","j","view","output","recursionDepth","labelType","pointer","flags","domainToAscii","domain","preprocessDomain","stringIsAscii","punycodeEncode","str","charIsAscii","base","tmin","tmax","skew","damp","initial_bias","initial_n","delta","bias","inputChars","asciiChars","basicCodePoints","handledCodePoints","inputCodePoints","inputLength","m","c","q","k","t","encodeDigit","div","adaptBias","d","n","numPoints","firstTime","version","resolve","qualifiedName","url","response","formatDnsMessage","error","formatted","formatRData","recordType"],"mappings":"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"}
1
+ {"version":3,"file":"universal-doh.umd.cjs","sources":["../lib/dns-message.ts","../lib/punycode.ts","../lib/index.ts"],"sourcesContent":["type RawDnsMessage = ArrayBuffer;\n\ninterface DnsMessage {\n id: number;\n // query (0), response (1)\n qr: BinaryFlag;\n /*\n 0 a standard query (QUERY)\n 1 an inverse query (IQUERY)\n 2 a server status request (STATUS)\n 3-15 reserved for future use\n */\n opcode: FourBitNumber;\n // Authoritative Answer\n aa: BinaryFlag;\n // TrunCation\n tc: BinaryFlag;\n // Recursion Desired\n rd: BinaryFlag;\n // Recursion Available\n ra: BinaryFlag;\n // reserved for future use - must be 0\n z: ThreeBitNumber;\n /*\n Response code\n 0 No error condition\n 1 Format error\n 2 Server failure\n 3 Name Error\n 4 Not Implemented\n 5 Refused\n 6-15 Reserved for future use.\n */\n rcode: FourBitNumber;\n // number of entries in the question section (0-65535)\n qdcount: number;\n // number of resource records in the answer section (0-65535)\n ancount: number;\n // number of name server resource records in the authority records section (0-65535)\n nscount: number;\n // number of resource records in the additional records section (0-65535)\n arcount: number;\n\n questions: DnsQuestion[];\n answers: DnsResourceRecord[];\n authorityRecords: DnsResourceRecord[];\n additionalRecords: Array<DnsOptRecord | DnsResourceRecord>;\n}\n\ntype Bytes = number[];\ntype Label = Bytes;\ntype DNSName = Label[];\n\ninterface DnsQuestion {\n qname: DNSName;\n // 16 bit unsigned integer\n qtype: number;\n // 16 bit unsigned integer\n qclass: number;\n}\n\ninterface Opt {\n optionCode: number;\n optionLength: number;\n optionData: Bytes;\n}\n\nexport interface DnsOptRecord {\n name: DNSName;\n type: 41;\n // 16 bit unsigned integer\n maxPayloadSize: number;\n // TTL field is used as the extended RCODE and flags\n // https://datatracker.ietf.org/doc/html/rfc6891#section-6.1.3\n extendedRcode: number;\n version: number;\n do: BinaryFlag;\n z: number;\n // 16 bit unsigned integer\n rdlength: number;\n // RDATA field is used for EDNS0 options\n rdata: Opt[];\n}\n\nexport interface DnsResourceRecord {\n name: DNSName;\n // 16 bit unsigned integer\n type: number;\n // 16 bit unsigned integer\n class: number;\n // 32 bit unsigned integer\n ttl: number;\n // 16 bit unsigned integer\n rdlength: number;\n rdata: Bytes;\n}\n\ntype BinaryFlag = 0 | 1;\ntype ThreeBitNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\ntype FourBitNumber =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15;\n\nexport function dnsNameToString(name: DNSName): string {\n return name.map((label) => String.fromCharCode(...label)).join(\".\");\n}\n\nexport function stringToDNSName(name: string): DNSName {\n // we can assume string is ascii but it may not be a valid domain name\n const labels = name.split(\".\").filter((label) => label.length > 0);\n const dnsName: DNSName = [];\n for (const label of labels) {\n if (label.length < 1 || label.length > 63) {\n throw new Error(\n `Label \"${label}\" must be between 1 and 63 characters long`,\n );\n }\n\n if (label.startsWith(\"-\") || label.endsWith(\"-\")) {\n throw new Error(`Label \"${label}\" cannot start or end with a hyphen`);\n }\n\n const bytes: Bytes = [];\n\n for (const char of label) {\n const code = char.charCodeAt(0);\n if (\n (code >= 48 && code <= 57) || // '0'-'9'\n (code >= 97 && code <= 122) || // 'a'-'z'\n code === 45 // '-'\n ) {\n bytes.push(code);\n } else {\n throw new Error(`Invalid character '${char}' in label \"${label}\"`);\n }\n }\n dnsName.push(bytes);\n }\n return dnsName;\n}\n\nfunction createDnsMessage() {\n return {\n id: 0,\n qr: 0,\n opcode: 0,\n aa: 0,\n tc: 0,\n rd: 0,\n ra: 0,\n z: 0,\n rcode: 0,\n qdcount: 0,\n ancount: 0,\n nscount: 0,\n arcount: 0,\n questions: [],\n answers: [],\n authorityRecords: [],\n additionalRecords: [],\n } as DnsMessage;\n}\n\nexport function createDnsQuery(questions: DnsQuestion[]): DnsMessage {\n const message = createDnsMessage();\n message.rd = 1;\n message.qdcount += questions.length;\n message.questions.push(...questions);\n\n // notify the server that we support EDNS0 by adding an OPT record\n message.arcount += 1;\n message.additionalRecords.push({\n name: [],\n type: 41,\n maxPayloadSize: 0xffff,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: 0,\n rdata: [],\n } as DnsOptRecord);\n\n // leave space for EDNS0 padding\n message.arcount += 1;\n\n return message;\n}\n\nexport function serializeDnsQuery(query: DnsMessage): RawDnsMessage {\n const buffer = new ArrayBuffer(1024);\n const message = new DataView(buffer);\n\n let offset = 0;\n offset = serializeHeader(message, offset, query);\n\n for (const question of query.questions) {\n offset = serializeQuestion(message, offset, question);\n }\n\n // we ignore the answers and authority records for queries,\n // but we include the additional records for EDNS0 support\n if (query.answers.length > 0 || query.authorityRecords.length > 0) {\n throw new Error(\"Cannot serialize answers or authority records for query\");\n }\n\n for (const record of query.additionalRecords) {\n offset = serializeResourceRecord(message, offset, record);\n }\n\n // add padding to the message for privacy\n offset = serializeEDNS0Padding(message, offset);\n\n return buffer.slice(0, offset);\n}\n\nfunction serializeName(message: DataView, offset: number, name: DNSName) {\n // TODO: consider implementing compression\n for (const label of name) {\n message.setUint8(offset++, label.length);\n for (const byte of label) {\n message.setUint8(offset++, byte);\n }\n }\n\n // empty label to terminate the domain name\n message.setUint8(offset++, 0);\n\n return offset;\n}\n\nfunction serializeResourceRecord(\n message: DataView,\n offset: number,\n record: DnsResourceRecord | DnsOptRecord,\n) {\n offset = serializeName(message, offset, record.name);\n message.setUint16(offset, record.type);\n offset += 2;\n\n if (record.type === 41) {\n message.setUint16(offset, (<DnsOptRecord>record).maxPayloadSize);\n } else {\n message.setUint16(offset, (<DnsResourceRecord>record).class);\n }\n offset += 2;\n\n let ttl;\n if (record.type === 41) {\n ttl = (<DnsOptRecord>record).extendedRcode << 24;\n ttl |= (<DnsOptRecord>record).version << 16;\n ttl |= (<DnsOptRecord>record).do << 15;\n ttl |= (<DnsOptRecord>record).z;\n } else {\n ttl = (<DnsResourceRecord>record).ttl;\n }\n\n message.setUint32(offset, ttl);\n offset += 4;\n message.setUint16(offset, record.rdlength);\n offset += 2;\n\n if (record.type === 41) {\n // OPT record\n for (const opt of (<DnsOptRecord>record).rdata) {\n message.setUint16(offset, opt.optionCode);\n offset += 2;\n message.setUint16(offset, opt.optionLength);\n offset += 2;\n for (const byte of opt.optionData) {\n message.setUint8(offset++, byte);\n }\n }\n } else {\n for (const byte of (<DnsResourceRecord>record).rdata) {\n message.setUint8(offset++, byte);\n }\n }\n\n return offset;\n}\n\nfunction serializeEDNS0Padding(message: DataView, offset: number) {\n // RFC 8467 - Recommended Strategy: Block-Length Padding\n\n // padding header of 4 bytes must be included\n const length = offset + 4;\n const paddingLength = Math.ceil(length / 128) * 128 - length;\n\n const padding = Array.from({ length: paddingLength }, () =>\n Math.floor(Math.random() * 0xff),\n );\n\n // RFC 7830\n const paddingRecord: DnsOptRecord = {\n name: [],\n type: 41,\n maxPayloadSize: 0,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: padding.length + 4,\n rdata: [\n { optionCode: 12, optionLength: padding.length, optionData: padding },\n ],\n };\n offset = serializeResourceRecord(message, offset, paddingRecord);\n\n return offset;\n}\n\nfunction serializeQuestion(\n message: DataView,\n offset: number,\n question: DnsQuestion,\n) {\n offset = serializeName(message, offset, question.qname);\n\n message.setUint16(offset, question.qtype);\n offset += 2;\n message.setUint16(offset, question.qclass);\n offset += 2;\n\n return offset;\n}\n\nfunction serializeHeader(\n message: DataView,\n offset: number,\n header: DnsMessage,\n) {\n // message id\n message.setUint16(offset, header.id);\n offset += 2;\n\n // flags\n message.setUint16(\n offset,\n ((header.qr & 0b1) << 15) |\n ((header.opcode & 0b1111) << 11) |\n ((header.aa & 0b1) << 10) |\n ((header.tc & 0b1) << 9) |\n ((header.rd & 0b1) << 8) |\n ((header.ra & 0b1) << 7) |\n ((header.z & 0b111) << 4) |\n (header.rcode & 0b1111),\n );\n offset += 2;\n\n // question records count\n message.setUint16(4, header.qdcount);\n offset += 2;\n\n // answer records count\n message.setUint16(6, header.ancount);\n offset += 2;\n\n // authority records count\n message.setUint16(8, header.nscount);\n offset += 2;\n\n // additional records count\n message.setUint16(10, header.arcount);\n offset += 2;\n\n return offset;\n}\n\nexport function parseDnsMessage(\n raw: RawDnsMessage,\n offset: number = 0,\n): DnsMessage {\n const rawView = new DataView(raw);\n const message = createDnsMessage();\n\n offset = parseHeader(rawView, offset, message);\n\n offset = parseQuestion(rawView, offset, message.qdcount, message.questions);\n\n offset = parseResourceRecords(\n rawView,\n offset,\n message.ancount,\n message.answers,\n );\n offset = parseResourceRecords(\n rawView,\n offset,\n message.nscount,\n message.authorityRecords,\n );\n offset = parseAdditionalRecords(\n rawView,\n offset,\n message.arcount,\n message.additionalRecords,\n );\n\n if (offset !== raw.byteLength) {\n // TODO: implement support for parsing padding and replace the warning with error\n throw new Error(\n `Unexpected end of message (offset: ${offset}, length: ${raw.byteLength})`,\n );\n }\n\n return message;\n}\n\nfunction parseQuestion(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsQuestion[],\n) {\n for (let i = 0; i < number; i++) {\n const qname: DNSName = [];\n offset = parseName(rawView, offset, qname, 0);\n\n const qtype = rawView.getUint16(offset);\n offset += 2;\n const qclass = rawView.getUint16(offset);\n offset += 2;\n\n records.push({ qname, qtype, qclass });\n }\n return offset;\n}\n\nfunction parseAdditionalRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: Array<DnsResourceRecord | DnsOptRecord>,\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n\n if (type === 41) {\n const record: DnsOptRecord = {\n name,\n type,\n maxPayloadSize: 0,\n extendedRcode: 0,\n version: 0,\n do: 0,\n z: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseOptRecordBody(rawView, offset, record);\n\n records.push(record);\n } else {\n const record: DnsResourceRecord = {\n name,\n type,\n class: 0,\n ttl: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseResourceRecordBody(rawView, offset, record);\n\n records.push(record);\n }\n }\n\n return offset;\n}\n\nfunction parseOptRecordBody(\n rawView: DataView,\n offset: number,\n record: DnsOptRecord,\n) {\n record.maxPayloadSize = rawView.getUint16(offset);\n offset += 2;\n\n // TTL field is used as the extended RCODE and flags\n const ttl = rawView.getUint32(offset);\n offset += 4;\n\n record.extendedRcode = (ttl & 0xff000000) >> 24;\n record.version = (ttl & 0x00ff0000) >> 16;\n record.do = ((ttl & 0x00008000) >> 15) as BinaryFlag;\n record.z = ttl & 0x00007fff;\n\n record.rdlength = rawView.getUint16(offset);\n offset += 2;\n\n const rdEnd = offset + record.rdlength;\n\n while (offset < rdEnd) {\n const optionCode = rawView.getUint16(offset);\n offset += 2;\n const optionLength = rawView.getUint16(offset);\n const opt = {\n optionCode,\n optionLength,\n optionData: [],\n } as Opt;\n offset += 2;\n for (let k = 0; k < opt.optionLength; k++) {\n opt.optionData.push(rawView.getUint8(offset++));\n }\n record.rdata.push(opt);\n }\n return offset;\n}\n\nfunction parseResourceRecordBody(\n rawView: DataView,\n offset: number,\n record: DnsResourceRecord,\n) {\n record.class = rawView.getUint16(offset);\n offset += 2;\n record.ttl = rawView.getUint32(offset);\n offset += 4;\n record.rdlength = rawView.getUint16(offset);\n offset += 2;\n for (let j = 0; j < record.rdlength; j++) {\n record.rdata.push(rawView.getUint8(offset++));\n }\n return offset;\n}\n\nfunction parseResourceRecords(\n rawView: DataView,\n offset: number,\n number: number,\n records: DnsResourceRecord[],\n) {\n for (let i = 0; i < number; i++) {\n const name: DNSName = [];\n offset = parseName(rawView, offset, name, 0);\n\n const type = rawView.getUint16(offset);\n offset += 2;\n\n const record: DnsResourceRecord = {\n name,\n type,\n class: 0,\n ttl: 0,\n rdlength: 0,\n rdata: [],\n };\n\n offset = parseResourceRecordBody(rawView, offset, record);\n\n records.push(record);\n }\n\n return offset;\n}\n\nfunction parseName(\n view: DataView,\n offset: number,\n output: DNSName,\n recursionDepth = 0,\n) {\n if (recursionDepth > 20) {\n throw new Error(\"Too many nested labels\");\n }\n\n let length = view.getUint8(offset++);\n while (length !== 0) {\n const labelType = length >> 6;\n if (labelType === 0b00) {\n // standard label\n const label = [];\n for (let i = 0; i < length; i++) {\n label.push(view.getUint8(offset++));\n }\n output.push(label);\n length = view.getUint8(offset++);\n } else if (labelType === 0b11) {\n // compressed label\n const pointer = ((length & 0b00111111) << 8) | view.getUint8(offset++);\n // ignore the offset as we returning from a \"jump\"\n parseName(view, pointer, output, recursionDepth + 1);\n break;\n } else {\n // we do not (yet) support extended label types (RFC2671)\n throw new Error(`Invalid label type: ${labelType.toString(2)}`);\n }\n }\n return offset;\n}\n\nfunction parseHeader(raw: DataView, offset: number, output: DnsMessage) {\n output.id = raw.getUint16(offset);\n offset += 2;\n\n const flags = raw.getUint16(offset);\n offset += 2;\n\n output.qr = ((flags & 0b1000000000000000) >> 15) as BinaryFlag;\n output.opcode = ((flags & 0b0111100000000000) >> 11) as FourBitNumber;\n output.aa = ((flags & 0b0000010000000000) >> 10) as BinaryFlag;\n output.tc = ((flags & 0b0000001000000000) >> 9) as BinaryFlag;\n output.rd = ((flags & 0b0000000100000000) >> 8) as BinaryFlag;\n output.ra = ((flags & 0b0000000010000000) >> 7) as BinaryFlag;\n output.z = ((flags & 0b0000000001110000) >> 4) as ThreeBitNumber;\n output.rcode = (flags & 0b0000000000001111) as FourBitNumber;\n\n output.qdcount = raw.getUint16(offset);\n offset += 2;\n\n output.ancount = raw.getUint16(offset);\n offset += 2;\n\n output.nscount = raw.getUint16(offset);\n offset += 2;\n\n output.arcount = raw.getUint16(offset);\n offset += 2;\n\n return offset;\n}\n","export function domainToAscii(domain: string) {\n const preprocessed = preprocessDomain(domain);\n const labels = preprocessed.split(\".\");\n\n const asciiLabels = labels.map((label) => {\n if (stringIsAscii(label)) {\n return label;\n } else {\n return \"xn--\" + punycodeEncode(label);\n }\n });\n\n return asciiLabels.join(\".\").toLowerCase();\n}\n\nfunction preprocessDomain(domain: string) {\n // https://unicode.org/reports/tr46/#TableDerivationStep1\n const exceptionalMapped = domain\n .replace(/[.。。]/gu, \".\")\n .replace(/ẞ/gu, \"ß\");\n\n // we normalize the input to Unicode Normalization Form KC\n const normalized = exceptionalMapped.normalize(\"NFKC\");\n\n // TODO: we deviate from the spec here to simplify the implementation\n // this may need to be revisited in the future\n\n // we should perform case folding here (NFKC_Casefold)\n // but we simplify this step to just lowercase the input instead\n const lowercased = normalized.toLowerCase();\n\n // remove all code points in the range U+FE00 to U+FE0F\n // (Unicode variation selectors) from the input\n // as they break emoji domains handling\n const filtered = lowercased.replace(/[\\uFE00-\\uFE0F]/gu, \"\");\n\n return filtered;\n}\n\nfunction stringIsAscii(str: string): boolean {\n return Array.from(str).every(charIsAscii);\n}\n\nfunction charIsAscii(char: string): boolean {\n return char.charCodeAt(0) < 128;\n}\n\nconst base = 36;\nconst tmin = 1;\nconst tmax = 26;\nconst skew = 38;\nconst damp = 700;\nconst initial_bias = 72;\nconst initial_n = 0x80;\n\nexport function punycodeEncode(str: string) {\n let n = initial_n;\n let delta = 0;\n let bias = initial_bias;\n const output: string[] = [];\n\n const inputChars = Array.from(str);\n\n // copy ascii chars to output\n const asciiChars = inputChars.filter(charIsAscii);\n const basicCodePoints = asciiChars.length;\n let handledCodePoints = basicCodePoints;\n output.push(...asciiChars);\n\n // append delimiter if we consumed any ascii chars\n if (basicCodePoints > 0) {\n output.push(\"-\");\n }\n\n const inputCodePoints = inputChars.map((char) => char.codePointAt(0)!);\n const inputLength = inputCodePoints.length;\n\n while (handledCodePoints < inputLength) {\n // Find the minimum code point >= n\n let m = Number.MAX_SAFE_INTEGER;\n for (const c of inputCodePoints) {\n if (c >= n && c < m) {\n m = c;\n }\n }\n\n delta += (m - n) * (handledCodePoints + 1);\n n = m;\n\n for (const c of inputCodePoints) {\n if (c < n) {\n delta++;\n } else if (c === n) {\n let q = delta;\n let k = base;\n\n while (true) {\n let t: number;\n if (k <= bias) {\n t = tmin;\n } else if (k >= bias + tmax) {\n t = tmax;\n } else {\n t = k - bias;\n }\n if (q < t) break;\n const code = t + ((q - t) % (base - t));\n output.push(encodeDigit(code));\n q = div(q - t, base - t);\n k += base;\n }\n\n output.push(encodeDigit(q));\n bias = adaptBias(\n delta,\n handledCodePoints + 1,\n handledCodePoints === basicCodePoints,\n );\n delta = 0;\n handledCodePoints++;\n }\n }\n\n delta++;\n n++;\n }\n\n return output.join(\"\");\n}\n\nfunction encodeDigit(d: number): string {\n return String.fromCharCode(d + 22 + 75 * Number(d < 26));\n}\n\nfunction div(n: number, d: number) {\n return Math.floor(n / d);\n}\n\nfunction adaptBias(delta: number, numPoints: number, firstTime: boolean) {\n if (firstTime) {\n delta = div(delta, damp);\n } else {\n delta = div(delta, 2);\n }\n\n delta += div(delta, numPoints);\n\n let k = 0;\n while (delta > div((base - tmin) * tmax, 2)) {\n delta = div(delta, base - tmin);\n\n k += 36;\n }\n\n return k + div((36 - 1 + 1) * delta, delta + skew);\n}\n","export const version = __LIB_VERSION__;\nimport type { DnsResourceRecord, DnsOptRecord } from \"./dns-message\";\nimport {\n serializeDnsQuery,\n createDnsQuery,\n parseDnsMessage,\n stringToDNSName,\n dnsNameToString,\n} from \"./dns-message\";\nimport { domainToAscii } from \"./punycode\";\n\nexport function resolve(server: string, name: string, type: string) {\n const qualifiedName = domainToAscii(name);\n\n const query = createDnsQuery([\n {\n qname: stringToDNSName(qualifiedName),\n qtype: parseInt(type, 10),\n qclass: 1, // INTERNET\n },\n ]);\n\n const buffer = serializeDnsQuery(query);\n\n const url = new URL(server);\n url.pathname = \"/dns-query\";\n\n return fetch(url, {\n method: \"POST\",\n mode: \"cors\",\n headers: {\n Accept: \"application/dns-message\",\n \"Content-Type\": \"application/dns-message\",\n },\n body: buffer,\n })\n .then((response) => {\n if (!response.ok) {\n return response.text().then((text) => {\n throw new Error(`HTTP ${response.status}: ${text}`);\n });\n }\n return response.arrayBuffer();\n })\n .then((buffer) => {\n const message = parseDnsMessage(buffer);\n return formatDnsMessage(message);\n })\n .catch((error) => {\n console.error(error);\n throw error;\n });\n}\n\nfunction formatDnsMessage(message: ReturnType<typeof parseDnsMessage>) {\n const formatted = {\n id: message.id,\n authoritativeAnswer: message.aa === 1,\n truncated: message.tc === 1,\n recursionAvailable: message.ra === 1,\n responseCode: message.rcode === 0 ? \"OK\" : \"ERROR\",\n questions: message.questions.map((question) => ({\n name: dnsNameToString(question.qname),\n type: question.qtype,\n })),\n answers: message.answers.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n authorityRecords: message.authorityRecords.map((record) => ({\n name: dnsNameToString(record.name),\n type: record.type,\n ttl: record.ttl,\n value: formatRData(record.type, record.rdata),\n })),\n additionalRecords: message.additionalRecords.map((record) => {\n if (record.type === 41) {\n return {\n name: dnsNameToString(record.name),\n type: record.type,\n maxPayloadSize: (<DnsOptRecord>record).maxPayloadSize,\n extendedRcode: (<DnsOptRecord>record).extendedRcode,\n version: (<DnsOptRecord>record).version,\n do: (<DnsOptRecord>record).do,\n z: (<DnsOptRecord>record).z,\n value: (<DnsOptRecord>record).rdata,\n };\n } else {\n return {\n name: dnsNameToString(record.name),\n type: record.type,\n class: (<DnsResourceRecord>record).class,\n ttl: (<DnsResourceRecord>record).ttl,\n value: formatRData(record.type, (<DnsResourceRecord>record).rdata),\n };\n }\n }),\n };\n return JSON.stringify(formatted, null, 2);\n}\n\nfunction formatRData(recordType: number, rdata: number[]) {\n // TODO: this has to be implemented in the parser as the data\n // may include dns names and labels like for CNAMEs\n // or TXT (where there are labels but merged into a single string)\n switch (recordType) {\n case 1:\n return rdata.join(\".\");\n case 28:\n return rdata.map((c) => c.toString(16)).join(\":\");\n default:\n return rdata;\n }\n}\n"],"names":["dnsNameToString","name","label","stringToDNSName","labels","dnsName","bytes","char","code","createDnsMessage","createDnsQuery","questions","message","serializeDnsQuery","query","buffer","offset","serializeHeader","question","serializeQuestion","record","serializeResourceRecord","serializeEDNS0Padding","serializeName","byte","ttl","opt","length","paddingLength","padding","paddingRecord","header","parseDnsMessage","raw","rawView","parseHeader","parseQuestion","parseResourceRecords","parseAdditionalRecords","number","records","i","qname","parseName","qtype","qclass","type","parseOptRecordBody","parseResourceRecordBody","rdEnd","optionCode","optionLength","k","j","view","output","recursionDepth","labelType","pointer","flags","domainToAscii","domain","preprocessDomain","stringIsAscii","punycodeEncode","str","charIsAscii","base","tmin","tmax","skew","damp","initial_bias","initial_n","delta","bias","inputChars","asciiChars","basicCodePoints","handledCodePoints","inputCodePoints","inputLength","m","c","q","t","encodeDigit","div","adaptBias","d","n","numPoints","firstTime","version","resolve","server","qualifiedName","url","response","text","formatDnsMessage","error","formatted","formatRData","recordType","rdata"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-doh",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "DNS over HTTPS universal TypeScript library",
5
5
  "keywords": [
6
6
  "universal-doh",