@@ -190,7 +190,8 @@ export async function startDnsServer() {
190190 if ( res . finished ) return next ( ) ;
191191
192192 const question = req . packet . questions [ 0 ] ;
193- if ( question . type == 'NS' ) {
193+ // Note: we have a different custom responder for NS records in dev
194+ if ( question . type == 'NS' && ! dev ) {
194195 res . packet . flags = res . packet . flags ;
195196 return res . answer ( makeNsAnswers ( question . name ) ) ;
196197 }
@@ -382,60 +383,71 @@ export async function startDnsServer() {
382383 // If there's already an answer, continue
383384 if ( res . finished ) return next ( ) ;
384385
386+ const question = req . packet . questions [ 0 ] ;
387+ const { type, name } = question ;
388+
389+ if ( name . endsWith ( '.localhost' ) ) {
390+ if ( type == 'A' ) {
391+ res . answer ( [
392+ {
393+ name,
394+ type,
395+ data : '127.0.0.1' ,
396+ ttl : DNS_TTL
397+ }
398+ ] ) ;
399+ return next ( ) ;
400+ } else if ( type == 'CNAME' ) {
401+ res . answer ( [
402+ {
403+ name,
404+ type,
405+ data : pubenv . PUBLIC_DOMAIN . split ( ':' ) [ 0 ] ,
406+ ttl : DNS_TTL
407+ }
408+ ] ) ;
409+ return next ( ) ;
410+ }
411+ }
412+
385413 const resolver = new dns . Resolver ( ) ;
386414 resolver . setServers ( defaultDnsServers ) ;
387415
388- // Collect answers asynchronously
389- const results = ( await Promise . all (
390- req . packet . questions . map (
391- ( question ) =>
392- new Promise ( ( returnAnswers ) => {
393- const { type, name } = question ;
394- switch ( type ) {
395- case 'TXT' :
396- case 'A' :
397- resolver . resolve ( name , type , ( err , ans ) => {
398- if ( ! err ) {
399- returnAnswers (
400- ( ans as AnyRecord [ ] ) . map ( ( answer ) => ( {
401- name,
402- type,
403- data : answer ,
404- ttl : DNS_TTL
405- } ) )
406- ) ;
407- } else {
408- returnAnswers ( [ ] ) ;
409- }
410- } ) ;
411- break ;
412- case 'NS' :
413- // Pretend to be the authoritative nameserver for everything so that resolving users
414- // by the authoritative namerserver always resolves locally during dev.
415- returnAnswers ( [
416- {
417- name,
418- type,
419- data : localServer ,
420- ttl : DNS_TTL
421- }
422- ] ) ;
423- default :
424- returnAnswers ( null ) ;
416+ switch ( type ) {
417+ case 'TXT' :
418+ case 'A' :
419+ resolver . resolve ( name , type , ( err , ans ) => {
420+ if ( ! err ) {
421+ res . answer (
422+ ( ans as AnyRecord [ ] ) . map ( ( answer ) => ( {
423+ name,
424+ type,
425+ data : answer ,
426+ ttl : DNS_TTL
427+ } ) ) as unknown as SupportedAnswer [ ]
428+ ) ;
429+ }
430+ } ) ;
431+ break ;
432+ case 'NS' :
433+ // Pretend to be the authoritative nameserver for every apex so that resolving users
434+ // by the authoritative namerserver always resolves locally during dev.
435+ if ( name . split ( '.' ) . length == 2 ) {
436+ res . answer ( [
437+ {
438+ name,
439+ type,
440+ data : localServer ,
441+ ttl : DNS_TTL
425442 }
426- } )
427- )
428- ) ) as ( SupportedAnswer [ ] | null ) [ ] ;
429-
430- // Return answers
431- const filtered = results
432- . filter ( ( x ) => ! ! x )
433- . map ( ( x ) => x as unknown as SupportedAnswer )
434- . flat ( ) ;
435- if ( filtered . length > 0 ) {
436- res . answer ( filtered ) ;
437- } else {
438- res . errors . nxDomain ( ) ;
443+ ] ) ;
444+ } else {
445+ res . answer ( [ ] ) ;
446+ // Don't go to next so that our normal default NS response doesn't get created.
447+ // We're trying to emulate the way that authoritative nameservers won't respond
448+ // to NS queries on subdomains that don't have custom nameservers.
449+ return ;
450+ }
439451 }
440452
441453 next ( ) ;
0 commit comments