Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3806

SRV responses exceeding 1024 bytes may result in error

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.17.1
    • Affects Version/s: None
    • Component/s: None
    • None

      For SRV record lookup, in _mongoc_get_rr_search, libmongoc has an initial buffer of 1024 for DNS answers. CDRIVER-3388 changed it to dynamically grow the buffer if res_nsearch or res_search returns a value greater than the buffer size. That aligns with Solaris documentation:

      The res_nsearch() and res_search() routines return a length that may be bigger
      than anslen. In that case, retry the query with a larger buf. The answer to the
      second query may be larger still], so it is recommended that you supply a buf
      larger than the answer returned by the previous query. answer must be large
      enough to receive a maximum UDP response from the server or parts of the answer will be silently discarded. The default maximum UDP response size is 512 bytes.

      However, BSD and Linux documentation don't appear explicit about what res_search and res_nsearch return if the answer exceeds the buffer size.

      The res_nquery(), res_query(), res_nsearch(), res_search(), res_nquerydomain(), res_querydomain(), res_nmkquery(), res_mkquery(), res_nsend(), and res_send() functions return the length of the response, or -1 if an error occurs.

      Testing on macOS, it appears that responses exceeding the buffer will return the entire buffer size (1024 on the first iteration) instead of the complete answer size.

      I tested this by setting up local SRV DNS records such that the response size exceeds 1024 bytes:

      kevin.albertson@Kevins-MacBook-Pro mongo-c-driver % dig  -t SRV _mongodb._tcp.lotsofrecords.mongodb.com
      
      ; <<>> DiG 9.10.6 <<>> -t SRV _mongodb._tcp.lotsofrecords.mongodb.com
      ;; global options: +cmd
      ;; Got answer:
      ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1438
      ;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 42, AUTHORITY: 0, ADDITIONAL: 0
      
      ;; QUESTION SECTION:
      ;_mongodb._tcp.lotsofrecords.mongodb.com. IN SRV
      
      ;; ANSWER SECTION:
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb0.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb1.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb2.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb3.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb4.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb5.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb6.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb7.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb8.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb9.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb10.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb11.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb12.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb13.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb14.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb15.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb16.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb17.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb18.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb19.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb20.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb21.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb22.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb23.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb24.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb25.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb26.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb27.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb28.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb29.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb30.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb31.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb32.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb33.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb34.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb35.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb36.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb37.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb38.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb39.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb40.mongodb.com.
      _mongodb._tcp.lotsofrecords.mongodb.com. 1 IN SRV 0 5 27020 mongodb41.mongodb.com.
      
      ;; Query time: 1 msec
      ;; SERVER: 127.0.0.1#53(127.0.0.1)
      ;; WHEN: Mon Oct 05 21:48:31 EDT 2020
      ;; MSG SIZE  rcvd: 1307
      

      And ran:

      kevin.albertson@Kevins-MacBook-Pro mongo-c-driver % ./cmake-build/src/libmongoc/example-client "mongodb+srv://lotsofrecords.mongodb.com"
      Cursor Failure: Invalid SRV answer for "_mongodb._tcp.lotsofrecords.mongodb.com"
      

      Setting a breakpoint in _mongoc_get_rr_search shows that res_nsearch returns the full buffer size of 1024 to indicate the message exceeds the size. The logic assumes that the return value is the full answer size.

            Assignee:
            kevin.albertson@mongodb.com Kevin Albertson
            Reporter:
            kevin.albertson@mongodb.com Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: