| 154 | } |
| 155 | |
| 156 | runLookup (origin, opts, cb) { |
| 157 | const ips = this.storage.get(origin.hostname) |
| 158 | |
| 159 | // If full, we just return the origin |
| 160 | if (ips == null && this.storage.full()) { |
| 161 | cb(null, origin) |
| 162 | return |
| 163 | } |
| 164 | |
| 165 | const newOpts = { |
| 166 | affinity: this.affinity, |
| 167 | dualStack: this.dualStack, |
| 168 | lookup: this.lookup, |
| 169 | pick: this.pick, |
| 170 | ...opts.dns, |
| 171 | maxTTL: this.#maxTTL, |
| 172 | maxItems: this.#maxItems |
| 173 | } |
| 174 | |
| 175 | // If no IPs we lookup |
| 176 | if (ips == null) { |
| 177 | this.lookup(origin, newOpts, (err, addresses) => { |
| 178 | if (err || addresses == null || addresses.length === 0) { |
| 179 | cb(err ?? new InformationalError('No DNS entries found')) |
| 180 | return |
| 181 | } |
| 182 | |
| 183 | this.setRecords(origin, addresses) |
| 184 | const records = this.storage.get(origin.hostname) |
| 185 | |
| 186 | const ip = this.pick( |
| 187 | origin, |
| 188 | records, |
| 189 | newOpts.affinity |
| 190 | ) |
| 191 | |
| 192 | let port |
| 193 | if (typeof ip.port === 'number') { |
| 194 | port = `:${ip.port}` |
| 195 | } else if (origin.port !== '') { |
| 196 | port = `:${origin.port}` |
| 197 | } else { |
| 198 | port = '' |
| 199 | } |
| 200 | |
| 201 | cb( |
| 202 | null, |
| 203 | new URL(`${origin.protocol}//${ |
| 204 | ip.family === 6 ? `[${ip.address}]` : ip.address |
| 205 | }${port}`) |
| 206 | ) |
| 207 | }) |
| 208 | } else { |
| 209 | // If there's IPs we pick |
| 210 | const ip = this.pick( |
| 211 | origin, |
| 212 | ips, |
| 213 | newOpts.affinity |