Skip to content

Commit c3d2782

Browse files
Allow valid SRV hostnames with less than 3 parts
1 parent a8a5577 commit c3d2782

File tree

5 files changed

+182
-187
lines changed

5 files changed

+182
-187
lines changed

driver-core/src/main/com/mongodb/connection/ClusterSettings.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import static com.mongodb.assertions.Assertions.isTrueArgument;
3737
import static com.mongodb.assertions.Assertions.notNull;
3838
import static com.mongodb.internal.connection.ServerAddressHelper.createServerAddress;
39-
import static java.lang.String.format;
4039
import static java.util.Collections.singletonList;
4140
import static java.util.Collections.unmodifiableList;
4241
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -607,11 +606,6 @@ private ClusterSettings(final Builder builder) {
607606
if (builder.srvHost.contains(":")) {
608607
throw new IllegalArgumentException("The srvHost can not contain a host name that specifies a port");
609608
}
610-
611-
if (builder.srvHost.split("\\.").length < 3) {
612-
throw new IllegalArgumentException(format("An SRV host name '%s' was provided that does not contain at least three parts. "
613-
+ "It must contain a hostname, domain name and a top level domain.", builder.srvHost));
614-
}
615609
}
616610

617611
if (builder.hosts.size() > 1 && builder.requiredClusterType == ClusterType.STANDALONE) {
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Initial DNS Seedlist Discovery tests
2+
3+
This directory contains platform-independent tests that drivers can use to prove their conformance to the Initial DNS
4+
Seedlist Discovery spec.
5+
6+
## Prose Tests
7+
8+
For the following prose tests, it is assumed drivers are be able to stub DNS results to easily test invalid DNS
9+
resolution results.
10+
11+
### 1. Allow SRVs with fewer than 3 `.` separated parts
12+
13+
When running validation on an SRV string before DNS resolution, do not throw a error due to number of SRV parts.
14+
15+
- `mongodb+srv://localhost`
16+
- `mongodb+srv://mongo.local`
17+
18+
### 2. Throw when return address does not end with SRV domain
19+
20+
When given a returned address that does NOT end with the original SRV's domain name, throw a runtime error.
21+
22+
For this test, run each of the following cases:
23+
24+
- the SRV `mongodb+srv://localhost` resolving to `localhost.mongodb`
25+
- the SRV `mongodb+srv://mongo.local` resolving to `test_1.evil.local`
26+
- the SRV `mongodb+srv://blogs.mongodb.com` resolving to `blogs.evil.com`
27+
28+
Remember, the domain of an SRV with one or two `.` separated parts is the SRVs entire hostname.
29+
30+
### 3. Throw when return address is identical to SRV hostname
31+
32+
When given a returned address that is identical to the SRV hostname and the SRV hostname has fewer than three `.`
33+
separated parts, throw a runtime error.
34+
35+
For this test, run each of the following cases:
36+
37+
- the SRV `mongodb+srv://localhost` resolving to `localhost`
38+
- the SRV `mongodb+srv://mongo.local` resolving to `mongo.local`
39+
40+
### 4. Throw when return address does not contain `.` separating shared part of domain
41+
42+
When given a returned address that does NOT share the domain name of the SRV record because it's missing a `.`, throw a
43+
runtime error.
44+
45+
For this test, run each of the following cases:
46+
47+
- the SRV `mongodb+srv://localhost` resolving to `test_1.cluster_1localhost`
48+
- the SRV `mongodb+srv://mongo.local` resolving to `test_1.my_hostmongo.local`
49+
- the SRV `mongodb+srv://blogs.mongodb.com` resolving to `cluster.testmongodb.com`
50+
51+
## Test Setup
52+
53+
The tests in the `replica-set` directory MUST be executed against a three-node replica set on localhost ports 27017,
54+
27018, and 27019 with replica set name `repl0`.
55+
56+
The tests in the `load-balanced` directory MUST be executed against a load-balanced sharded cluster with the mongos
57+
servers running on localhost ports 27017 and 27018 and `--loadBalancerPort` 27050 and 27051, respectively (corresponding
58+
to the script in
59+
[drivers-evergreen-tools](https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/run-load-balancer.sh)).
60+
The load balancers, shard servers, and config servers may run on any open ports.
61+
62+
The tests in the `sharded` directory MUST be executed against a sharded cluster with the mongos servers running on
63+
localhost ports 27017 and 27018. Shard servers and config servers may run on any open ports.
64+
65+
In all cases, the clusters MUST be started with SSL enabled.
66+
67+
To run the tests that accompany this spec, you need to configure the SRV and TXT records with a real name server. The
68+
following records are required for these tests:
69+
70+
```
71+
Record TTL Class Address
72+
localhost.test.build.10gen.cc. 86400 IN A 127.0.0.1
73+
localhost.sub.test.build.10gen.cc. 86400 IN A 127.0.0.1
74+
75+
Record TTL Class Port Target
76+
_mongodb._tcp.test1.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
77+
_mongodb._tcp.test1.test.build.10gen.cc. 86400 IN SRV 27018 localhost.test.build.10gen.cc.
78+
_mongodb._tcp.test2.test.build.10gen.cc. 86400 IN SRV 27018 localhost.test.build.10gen.cc.
79+
_mongodb._tcp.test2.test.build.10gen.cc. 86400 IN SRV 27019 localhost.test.build.10gen.cc.
80+
_mongodb._tcp.test3.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
81+
_mongodb._tcp.test5.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
82+
_mongodb._tcp.test6.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
83+
_mongodb._tcp.test7.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
84+
_mongodb._tcp.test8.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
85+
_mongodb._tcp.test10.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
86+
_mongodb._tcp.test11.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
87+
_mongodb._tcp.test12.test.build.10gen.cc. 86400 IN SRV 27017 localhost.build.10gen.cc.
88+
_mongodb._tcp.test13.test.build.10gen.cc. 86400 IN SRV 27017 test.build.10gen.cc.
89+
_mongodb._tcp.test14.test.build.10gen.cc. 86400 IN SRV 27017 localhost.not-test.build.10gen.cc.
90+
_mongodb._tcp.test15.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.not-build.10gen.cc.
91+
_mongodb._tcp.test16.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.not-10gen.cc.
92+
_mongodb._tcp.test17.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.not-cc.
93+
_mongodb._tcp.test18.test.build.10gen.cc. 86400 IN SRV 27017 localhost.sub.test.build.10gen.cc.
94+
_mongodb._tcp.test19.test.build.10gen.cc. 86400 IN SRV 27017 localhost.evil.build.10gen.cc.
95+
_mongodb._tcp.test19.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
96+
_mongodb._tcp.test20.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
97+
_mongodb._tcp.test21.test.build.10gen.cc. 86400 IN SRV 27017 localhost.test.build.10gen.cc.
98+
_customname._tcp.test22.test.build.10gen.cc 86400 IN SRV 27017 localhost.test.build.10gen.cc.
99+
_mongodb._tcp.test23.test.build.10gen.cc. 86400 IN SRV 8000 localhost.test.build.10gen.cc.
100+
_mongodb._tcp.test24.test.build.10gen.cc. 86400 IN SRV 8000 localhost.test.build.10gen.cc.
101+
102+
Record TTL Class Text
103+
test5.test.build.10gen.cc. 86400 IN TXT "replicaSet=repl0&authSource=thisDB"
104+
test6.test.build.10gen.cc. 86400 IN TXT "replicaSet=repl0"
105+
test6.test.build.10gen.cc. 86400 IN TXT "authSource=otherDB"
106+
test7.test.build.10gen.cc. 86400 IN TXT "ssl=false"
107+
test8.test.build.10gen.cc. 86400 IN TXT "authSource"
108+
test10.test.build.10gen.cc. 86400 IN TXT "socketTimeoutMS=500"
109+
test11.test.build.10gen.cc. 86400 IN TXT "replicaS" "et=rep" "l0"
110+
test20.test.build.10gen.cc. 86400 IN TXT "loadBalanced=true"
111+
test21.test.build.10gen.cc. 86400 IN TXT "loadBalanced=false"
112+
test24.test.build.10gen.cc. 86400 IN TXT "loadBalanced=true"
113+
```
114+
115+
Notes:
116+
117+
- `test4` is omitted deliberately to test what happens with no SRV record.
118+
- `test9` is missing because it was deleted during the development of the tests.
119+
- The missing `test.` sub-domain in the SRV record target for `test12` is deliberate.
120+
- `test22` is used to test a custom service name (`customname`).
121+
- `test23` and `test24` point to port 8000 (HAProxy) and are used for load-balanced tests.
122+
123+
In our tests we have used `localhost.test.build.10gen.cc` as the domain, and then configured
124+
`localhost.test.build.10gen.cc` to resolve to 127.0.0.1.
125+
126+
You need to adapt the records shown above to replace `test.build.10gen.cc` with your own domain name, and update the
127+
"uri" field in the YAML or JSON files in this directory with the actual domain.
128+
129+
## Test Format and Use
130+
131+
These YAML and JSON files contain the following fields:
132+
133+
- `uri`: a `mongodb+srv` connection string
134+
- `seeds`: the expected set of initial seeds discovered from the SRV record
135+
- `numSeeds`: the expected number of initial seeds discovered from the SRV record. This is mainly used to test
136+
`srvMaxHosts`, since randomly selected hosts cannot be deterministically asserted.
137+
- `hosts`: the discovered topology's list of hosts once SDAM completes a scan
138+
- `numHosts`: the expected number of hosts discovered once SDAM completes a scan. This is mainly used to test
139+
`srvMaxHosts`, since randomly selected hosts cannot be deterministically asserted.
140+
- `options`: the parsed [URI options](../../uri-options/uri-options.md) as discovered from the
141+
[Connection String](../../connection-string/connection-string-spec.md)'s "Connection Options" component and SRV
142+
resolution (e.g. TXT records, implicit `tls` default).
143+
- `parsed_options`: additional, parsed options from other
144+
[Connection String](../../connection-string/connection-string-spec.md) components. This is mainly used for asserting
145+
`UserInfo` (as `user` and `password`) and `Auth database` (as `auth_database`).
146+
- `error`: indicates that the parsing of the URI, or the resolving or contents of the SRV or TXT records included
147+
errors.
148+
- `comment`: a comment to indicate why a test would fail.
149+
- `ping`: if false, the test runner should not run a "ping" operation.
150+
151+
For each YAML file:
152+
153+
- Create a MongoClient initialized with the `mongodb+srv` connection string.
154+
- Run a "ping" operation unless `ping` is false or `error` is true.
155+
156+
Assertions:
157+
158+
- If `seeds` is specified, drivers SHOULD verify that the set of hosts in the client's initial seedlist matches the list
159+
in `seeds`. If `numSeeds` is specified, drivers SHOULD verify that the size of that set matches `numSeeds`.
160+
161+
- If `hosts` is specified, drivers MUST verify that the set of ServerDescriptions in the client's TopologyDescription
162+
eventually matches the list in `hosts`. If `numHosts` is specified, drivers MUST verify that the size of that set
163+
matches `numHosts`.
164+
165+
- If `options` is specified, drivers MUST verify each of the values under `options` match the MongoClient's parsed value
166+
for that option. There may be other options parsed by the MongoClient as well, which a test does not verify.
167+
168+
- If `parsed_options` is specified, drivers MUST verify that each of the values under `parsed_options` match the
169+
MongoClient's parsed value for that option. Supported values include, but are not limited to, `user` and `password`
170+
(parsed from `UserInfo`) and `auth_database` (parsed from `Auth database`).
171+
172+
- If `error` is specified and `true`, drivers MUST verify that initializing the MongoClient throws an error. If `error`
173+
is not specified or is `false`, both initializing the MongoClient and running a ping operation must succeed without
174+
throwing any errors.
175+
176+
- If `ping` is not specified or `true`, drivers MUST verify that running a "ping" operation using the initialized
177+
MongoClient succeeds. If `ping` is `false`, drivers MUST NOT run a "ping" operation.
178+
179+
> **Note:** These tests are expected to be run against MongoDB databases with and without authentication enabled. The
180+
> "ping" operation does not require authentication so should succeed with URIs that contain no userinfo (i.e. no
181+
> username and password). Tests with URIs that contain userinfo always set `ping` to `false` because some drivers will
182+
> fail handshake on a connection if userinfo is provided but incorrect.

0 commit comments

Comments
 (0)