Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-5042

Relax SRV record validation to account for a "." suffix

    • 3
    • Not Needed
    • v4.x
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      How are you using Mongo? What version of the server and driver are you using?

      5.0 driver code

      What is the feature/improvement you would like?

      SRV record validation should account for possible trailing "." on SRV records without throwing an error.  For example, the SRV host "freecluster-oztdp.mongodb-dev.net" could resolve to SRV records like:

      freecluster-shard-00-00-oztdp.mongodb-dev.net.
      freecluster-shard-00-01-oztdp.mongodb-dev.net.
      freecluster-shard-00-02-oztdp.mongodb-dev.net.
      

      and these should not fail validation in the matchesParentDomain function. 

      What use case would this feature/improvement enable?

      I suspect this would fix (or work around, depending on your perspective)  the issue reported about Deno by alex.bevilacqua@mongodb.com here: https://github.com/denoland/deno/issues/16633. To confirm this I ran the following script, which is just stripping out everything but the SRV lookup logic from the driver's connection_string.ts :

      Unable to find source-code formatter for language: ts. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      import * as dns from "node:dns";
      
      function matchesParentDomain(srvAddress: string, parentDomain: string): boolean {
        const regex = /^.*?\./;
        const srv = `.${srvAddress.replace(regex, '')}`;
        const parent = `.${parentDomain.replace(regex, '')}`;
        return srv.endsWith(parent);
      }
      
      async function main() {
        const lookupAddress = 'freecluster-oztdp.mongodb-dev.net';
        const srvServiceName = 'mongodb';
        const addresses = await dns.promises.resolveSrv(
          `_${srvServiceName}._tcp.${lookupAddress}`
        );
      
        console.log('%s', lookupAddress);
        console.log('%s', srvServiceName);
      
        for (const { name } of addresses) {
          console.log('%s', name);
          if (!matchesParentDomain(name, lookupAddress)) {
            console.log('Name does not match parent domain');
          }
        }
      }
      
      main().then(r => console.log('Done')) 
      

      WIth npx, the output is

      % npx ts-node srv_test.ts
      freecluster-oztdp.mongodb-dev.net
      mongodb
      freecluster-shard-00-00-oztdp.mongodb-dev.net
      freecluster-shard-00-01-oztdp.mongodb-dev.net
      freecluster-shard-00-02-oztdp.mongodb-dev.net
      Done
      

      while with deno it's:

      % deno run --unstable --allow-all srv_test.ts
      freecluster-oztdp.mongodb-dev.net
      mongodb
      freecluster-shard-00-00-oztdp.mongodb-dev.net.
      Name does not match parent domain
      freecluster-shard-00-01-oztdp.mongodb-dev.net.
      Name does not match parent domain
      freecluster-shard-00-02-oztdp.mongodb-dev.net.
      Name does not match parent domain
      Done
      

      Note that the "raw" SRV record does contain the trailing ".", but it seems like Node strips that "." from the response, while deno does not.

      I also notice that in the Java driver the following check exists:

      // The "raw" srvRecord looks like: 
      // "0 0 27017 freecluster-shard-00-00-oztdp.mongodb-dev.net."
      // coming from Java's DNS lookup library.  Note the trailing "."
      String[] split = srvRecord.split(" ");  
      String resolvedHost = split[3].endsWith(".")        
            ? split[3].substring(0, split[3].length() - 1)        
            : split[3];
      

      So it's accounting for the possibility of a trailing ".", but does not assume it will be there. I don't recall why it was done this way, and I don't see anything in the spec to account for the conditional logic.

            Assignee:
            neal.beeken@mongodb.com Neal Beeken
            Reporter:
            jeff.yemin@mongodb.com Jeffrey Yemin
            Durran Jordan
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: