'use strict'; const {isIP}=require('node:net'); const dns=require('node:dns').promises; // Resolve once in the broker and bind the approved numeric address to the dial. // Active IP policy uses this approved tuple for numeric proxy CONNECT; ordinary // hostname CONNECT remains supported when that origin IP policy is inactive. function createDnsPolicyRoute({lookup=dns.lookup,blocked,current}={}){ if(typeof lookup!=='function'||typeof blocked!=='function'||typeof current!=='function')throw Error('broker-route-denied'); return async({hostname,port,signal})=>{ const check=()=>{if(signal?.aborted||current()!==true)throw Error('broker-route-denied');}; try{ check();if(typeof hostname!=='string'||!hostname||hostname.length>253||!Number.isSafeInteger(port)||port<1||port>65535)throw Error(); const literal=hostname.replace(/^\[|\]$/g,''); if(isIP(literal)){if(blocked(literal))throw Error();check();return Object.freeze({approved:true,address:literal,port});} const records=await lookup(hostname,{all:true,verbatim:true});check(); if(!Array.isArray(records)||!records.length||records.length>64||records.some(r=>!r||typeof r.address!=='string'||!isIP(r.address)||blocked(r.address)))throw Error(); const address=records[0].address;check();return Object.freeze({approved:true,address,port}); }catch{throw Error('broker-route-denied');} }; } function assertSupportedDns(policy,network,{numericOriginSupported=false}={}){ if(policy.enterprise?.dns?.mode==='secure'||!numericOriginSupported&&network.mode==='fixed_servers'&&policy.security?.dns?.enabled!==false&&policy.security?.dns?.blockedIPs?.length)throw Error('broker-route-unsupported'); } module.exports={createDnsPolicyRoute,assertSupportedDns};