Skip to content

Commit 9c19368

Browse files
committed
rollback extra changes
1 parent d2a51d8 commit 9c19368

32 files changed

+123
-239
lines changed

.evergreen/run-kms-servers.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ cd ${DRIVERS_TOOLS}/.evergreen/csfle
22
. ./activate_venv.sh
33
# by default it always runs on port 5698
44
./kmstlsvenv/bin/python3 -u kms_kmip_server.py &
5-
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 9000 &
6-
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 9001 &
7-
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem --port 9002 --require_client_cert &
5+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 8000 &
6+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 8001 &
7+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem --port 8002 --require_client_cert &

docs/errors.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ This class should **never** be directly instantiated.
9595

9696
### MongoUnexpectedServerResponseError
9797

98-
xxx
98+
Intended for the scenario where the MongoDB returns an unexpected response in relation to some state the driver is in
99+
This error should **NOT** represent a response that couldn't be parsed due to errors in protocol formatting.
100+
101+
Ex. Server selection results in a feature detection change, this is not a direct unexpected response, but if we've begun retrying an operation and serverSelection during that retry returns a server with a lower wireVersion than expected, we can no longer proceed with the retry.
102+
99103

100104
### `MongoNetworkError`
101105

src/change_stream.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import Denque = require('denque');
22
import type { Readable } from 'stream';
33

44
import type { Document, Timestamp } from './bson';
5-
import { MONGODB_WIRE_VERSION } from './cmap/wire_protocol/constants';
65
import { Collection } from './collection';
76
import {
87
AbstractCursor,
@@ -463,10 +462,7 @@ export class ChangeStreamCursor<TSchema extends Document = Document> extends Abs
463462
const resumeKey =
464463
this.options.startAfter && !this.hasReceived ? 'startAfter' : 'resumeAfter';
465464
Reflect.set(result, resumeKey, this.resumeToken);
466-
} else if (
467-
this.startAtOperationTime &&
468-
maxWireVersion(this.server) >= MONGODB_WIRE_VERSION.REPLICA_SET_TRANSACTIONS
469-
) {
465+
} else if (this.startAtOperationTime && maxWireVersion(this.server) >= 7) {
470466
result.startAtOperationTime = this.startAtOperationTime;
471467
}
472468
}
@@ -517,7 +513,7 @@ export class ChangeStreamCursor<TSchema extends Document = Document> extends Abs
517513
this.startAtOperationTime == null &&
518514
this.resumeAfter == null &&
519515
this.startAfter == null &&
520-
maxWireVersion(server) >= MONGODB_WIRE_VERSION.REPLICA_SET_TRANSACTIONS
516+
maxWireVersion(server) >= 7
521517
) {
522518
this.startAtOperationTime = response.operationTime;
523519
}

src/cmap/auth/mongo_credentials.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import type { Document } from '../../bson';
33
import { MongoAPIError, MongoMissingCredentialsError } from '../../error';
44
import { emitWarningOnce } from '../../utils';
5-
import { MONGODB_WIRE_VERSION } from '../wire_protocol/constants';
65
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './providers';
76

87
// https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
@@ -17,7 +16,7 @@ function getDefaultAuthMechanism(hello?: Document): AuthMechanism {
1716
}
1817

1918
// Fallback to legacy selection method. If wire version >= 3, use scram-sha-1
20-
if (hello.maxWireVersion >= MONGODB_WIRE_VERSION.RELEASE_2_7_7) {
19+
if (hello.maxWireVersion >= 3) {
2120
return AuthMechanism.MONGODB_SCRAM_SHA1;
2221
}
2322
}

src/cmap/auth/mongodb_aws.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
MongoRuntimeError
1212
} from '../../error';
1313
import { Callback, maxWireVersion, ns } from '../../utils';
14-
import { MONGODB_WIRE_VERSION } from '../wire_protocol/constants';
1514
import { AuthContext, AuthProvider } from './auth_provider';
1615
import { MongoCredentials } from './mongo_credentials';
1716
import { AuthMechanism } from './providers';
@@ -45,7 +44,7 @@ export class MongoDBAWS extends AuthProvider {
4544
}
4645
const { sign } = aws4;
4746

48-
if (maxWireVersion(connection) < MONGODB_WIRE_VERSION.RESUMABLE_INITIAL_SYNC) {
47+
if (maxWireVersion(connection) < 9) {
4948
callback(
5049
new MongoCompatibilityError(
5150
'MONGODB-AWS authentication requires MongoDB version 4.4 or later'

src/cmap/connection.ts

+29-55
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import {
5353
import type { Stream } from './connect';
5454
import { MessageStream, OperationDescription } from './message_stream';
5555
import { StreamDescription, StreamDescriptionOptions } from './stream_description';
56-
import { MONGODB_WIRE_VERSION } from './wire_protocol/constants';
5756
import { applyCommonQueryOptions, getReadPreference, isSharded } from './wire_protocol/shared';
5857

5958
/** @internal */
@@ -251,35 +250,9 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
251250
/* ignore errors, listen to `close` instead */
252251
});
253252

254-
const eventHandlerFactory = (event: 'error' | 'close' | 'timeout') =>
255-
[
256-
event,
257-
(error?: Error) => {
258-
if (this.closed) {
259-
return;
260-
}
261-
this.closed = true;
262-
263-
switch (event) {
264-
case 'error':
265-
this.onError(error);
266-
break;
267-
case 'close':
268-
this.onClose();
269-
break;
270-
case 'timeout':
271-
this.onTimeout();
272-
break;
273-
}
274-
275-
this[kQueue].clear();
276-
this.emit(Connection.CLOSE);
277-
}
278-
] as const;
279-
280-
this[kMessageStream].on(...eventHandlerFactory('error'));
281-
stream.on(...eventHandlerFactory('close'));
282-
stream.on(...eventHandlerFactory('timeout'));
253+
this[kMessageStream].on('error', error => this.handleIssue({ destroy: error }));
254+
stream.on('close', () => this.handleIssue({ isClose: true }));
255+
stream.on('timeout', () => this.handleIssue({ isTimeout: true, destroy: true }));
283256

284257
// hook the message stream up to the passed in stream
285258
stream.pipe(this[kMessageStream]);
@@ -335,29 +308,33 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
335308
this[kLastUseTime] = now();
336309
}
337310

338-
onTimeout() {
339-
this[kStream].destroy();
340-
const beforeHandshake = {
341-
beforeHandshake: this.hello == null
342-
};
343-
const msg = `connection ${this.id} to ${this.address} timed out`;
344-
345-
for (const [, op] of this[kQueue]) {
346-
op.cb(new MongoNetworkTimeoutError(msg, beforeHandshake));
311+
handleIssue(issue: { isTimeout?: boolean; isClose?: boolean; destroy?: boolean | Error }): void {
312+
if (this.closed) {
313+
return;
347314
}
348-
}
349315

350-
onClose() {
351-
for (const [, op] of this[kQueue]) {
352-
op.cb(new MongoNetworkError(`connection ${this.id} to ${this.address} closed`));
316+
if (issue.destroy) {
317+
this[kStream].destroy(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
353318
}
354-
}
355319

356-
onError(error?: Error) {
357-
this[kStream].destroy(error);
320+
this.closed = true;
321+
358322
for (const [, op] of this[kQueue]) {
359-
op.cb(error);
323+
if (issue.isTimeout) {
324+
op.cb(
325+
new MongoNetworkTimeoutError(`connection ${this.id} to ${this.address} timed out`, {
326+
beforeHandshake: this.hello == null
327+
})
328+
);
329+
} else if (issue.isClose) {
330+
op.cb(new MongoNetworkError(`connection ${this.id} to ${this.address} closed`));
331+
} else {
332+
op.cb(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
333+
}
360334
}
335+
336+
this[kQueue].clear();
337+
this.emit(Connection.CLOSE);
361338
}
362339

363340
destroy(): void;
@@ -566,7 +543,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
566543
return;
567544
}
568545

569-
if (wireVersion < MONGODB_WIRE_VERSION.FIND_COMMAND) {
546+
if (wireVersion < 4) {
570547
const getMoreOp = new GetMore(ns.toString(), cursorId, { numberToReturn: options.batchSize });
571548
const queryOptions = applyCommonQueryOptions(
572549
{},
@@ -620,7 +597,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
620597
throw new MongoRuntimeError(`Invalid list of cursor ids provided: ${cursorIds}`);
621598
}
622599

623-
if (maxWireVersion(this) < MONGODB_WIRE_VERSION.FIND_COMMAND) {
600+
if (maxWireVersion(this) < 4) {
624601
try {
625602
write(
626603
this,
@@ -678,12 +655,12 @@ export class CryptoConnection extends Connection {
678655
}
679656

680657
const serverWireVersion = maxWireVersion(this);
681-
if (serverWireVersion === MONGODB_WIRE_VERSION.UNKNOWN) {
658+
if (serverWireVersion === 0) {
682659
// This means the initial handshake hasn't happened yet
683660
return super.command(ns, cmd, options, callback);
684661
}
685662

686-
if (serverWireVersion < MONGODB_WIRE_VERSION.SHARDED_TRANSACTIONS) {
663+
if (serverWireVersion < 8) {
687664
callback(
688665
new MongoCompatibilityError('Auto-encryption requires a minimum MongoDB version of 4.2')
689666
);
@@ -720,10 +697,7 @@ function supportsOpMsg(conn: Connection) {
720697
return false;
721698
}
722699

723-
return (
724-
maxWireVersion(conn) >= MONGODB_WIRE_VERSION.SUPPORTS_OP_MSG &&
725-
!description.__nodejs_mock_server__ // mock server does not support OP_MSG
726-
);
700+
return maxWireVersion(conn) >= 6 && !description.__nodejs_mock_server__;
727701
}
728702

729703
function messageHandler(conn: Connection) {

src/cmap/errors.ts

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import type { ConnectionPool } from './connection_pool';
33

44
/**
55
* An error indicating a connection pool is closed
6-
*
7-
* @public
8-
*
96
* @category Error
107
*/
118
export class PoolClosedError extends MongoDriverError {

src/cmap/wire_protocol/constants.ts

+2-49
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,7 @@
1-
/**
2-
* All known MongoDB Wire versions, used to determine basic feature support
3-
* - see the [server enum](https://github.com/mongodb/mongo/blob/fe4cf6134b16f102591053d6f4fe11e5cc0eb3ec/src/mongo/db/wire_version.h#L57)
4-
* - (note: the is a link to a commit so you can find the file, you should then check the main branch)
5-
*/
6-
export const MONGODB_WIRE_VERSION = Object.freeze({
7-
/** A helper wire version, 0 means no information about what is supported on the server is known */
8-
UNKNOWN: 0,
9-
/** Everything before we started tracking. */
10-
RELEASE_2_4_AND_BEFORE: 0,
11-
/** The aggregation command may now be requested to return cursors. */
12-
AGG_RETURNS_CURSORS: 1,
13-
/** insert, update, and delete batch command */
14-
BATCH_COMMANDS: 2,
15-
/** support SCRAM-SHA1, listIndexes, listCollections, new explain */
16-
RELEASE_2_7_7: 3,
17-
/** Support find and getMore commands, as well as OP_COMMAND in mongod (but not mongos). */
18-
FIND_COMMAND: 4,
19-
/** Supports all write commands take a write concern. */
20-
COMMANDS_ACCEPT_WRITE_CONCERN: 5,
21-
/** Supports the new OP_MSG wireprotocol (3.6+). */
22-
SUPPORTS_OP_MSG: 6,
23-
/** Supports replica set transactions (4.0+). */
24-
REPLICA_SET_TRANSACTIONS: 7,
25-
/** Supports sharded transactions (4.2+). */
26-
SHARDED_TRANSACTIONS: 8,
27-
/** Supports resumable initial sync (4.4+). */
28-
RESUMABLE_INITIAL_SYNC: 9,
29-
/** Supports features available from 4.7 and onwards. */
30-
WIRE_VERSION_47: 10,
31-
/** Supports features available from 4.8 and onwards. */
32-
WIRE_VERSION_48: 11,
33-
/**
34-
* Supports features available from 4.9 and onwards.
35-
* - EstimatedDocumentCountOperation can run as an aggregation
36-
*/
37-
WIRE_VERSION_49: 12,
38-
/**
39-
* Supports features available from 5.0 and onwards.
40-
* - Writes to secondaries $out/$merge
41-
* - Snapshot reads
42-
*/
43-
WIRE_VERSION_50: 13,
44-
/** Supports features available from 5.1 and onwards. */
45-
WIRE_VERSION_51: 14
46-
} as const);
47-
481
export const MIN_SUPPORTED_SERVER_VERSION = '3.6';
492
export const MAX_SUPPORTED_SERVER_VERSION = '5.1';
50-
export const MIN_SUPPORTED_WIRE_VERSION = MONGODB_WIRE_VERSION.SUPPORTS_OP_MSG;
51-
export const MAX_SUPPORTED_WIRE_VERSION = MONGODB_WIRE_VERSION.WIRE_VERSION_51;
3+
export const MIN_SUPPORTED_WIRE_VERSION = 6;
4+
export const MAX_SUPPORTED_WIRE_VERSION = 14;
525
export const OP_REPLY = 1;
536
export const OP_UPDATE = 2001;
547
export const OP_INSERT = 2002;

src/error.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Document } from './bson';
2-
import { MONGODB_WIRE_VERSION } from './cmap/wire_protocol/constants';
32
import type { TopologyVersion } from './sdam/server_description';
43
import type { TopologyDescription } from './sdam/topology_description';
54

@@ -101,8 +100,6 @@ export interface ErrorDescription extends Document {
101100
errInfo?: Document;
102101
}
103102

104-
const kCreated = Symbol('created');
105-
106103
/**
107104
* @public
108105
* @category Error
@@ -113,7 +110,6 @@ const kCreated = Symbol('created');
113110
export class MongoError extends Error {
114111
/** @internal */
115112
[kErrorLabels]: Set<string>;
116-
[kCreated]: Date;
117113
/**
118114
* This is a number in MongoServerError and a string in MongoDriverError
119115
* @privateRemarks
@@ -128,7 +124,6 @@ export class MongoError extends Error {
128124
} else {
129125
super(message);
130126
}
131-
this[kCreated] = new Date();
132127
}
133128

134129
get name(): string {
@@ -756,7 +751,7 @@ export function isRetryableWriteError(error: MongoError, maxWireVersion: number)
756751
return false;
757752
}
758753

759-
if (maxWireVersion >= MONGODB_WIRE_VERSION.RESUMABLE_INITIAL_SYNC) {
754+
if (maxWireVersion >= 9) {
760755
// After 4.4 the error label is the only source of truth for retry writes
761756
return error.hasErrorLabel(MONGODB_ERROR_LABELS.RetryableWriteError);
762757
} else if (error.hasErrorLabel(MONGODB_ERROR_LABELS.RetryableWriteError)) {
@@ -884,7 +879,7 @@ export function isResumableError(error?: MongoError, wireVersion?: number): bool
884879
return true;
885880
}
886881

887-
if (wireVersion != null && wireVersion >= MONGODB_WIRE_VERSION.RESUMABLE_INITIAL_SYNC) {
882+
if (wireVersion != null && wireVersion >= 9) {
888883
// DRIVERS-1308: For 4.4 drivers running against 4.4 servers, drivers will add a special case to treat the CursorNotFound error code as resumable
889884
if (error && error instanceof MongoError && error.code === MONGODB_ERROR_CODES.CursorNotFound) {
890885
return true;

src/operations/add_user.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as crypto from 'crypto';
22

33
import type { Document } from '../bson';
4-
import { MONGODB_WIRE_VERSION } from '../cmap/wire_protocol/constants';
54
import type { Db } from '../db';
65
import { MongoInvalidArgumentError } from '../error';
76
import type { Server } from '../sdam/server';
@@ -76,8 +75,7 @@ export class AddUserOperation extends CommandOperation<Document> {
7675
roles = Array.isArray(options.roles) ? options.roles : [options.roles];
7776
}
7877

79-
const digestPassword =
80-
getTopology(db).lastHello().maxWireVersion >= MONGODB_WIRE_VERSION.REPLICA_SET_TRANSACTIONS;
78+
const digestPassword = getTopology(db).lastHello().maxWireVersion >= 7;
8179

8280
let userPassword = password;
8381

src/operations/aggregate.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Document } from '../bson';
2-
import { MONGODB_WIRE_VERSION } from '../cmap/wire_protocol/constants';
32
import { MongoInvalidArgumentError } from '../error';
43
import type { Server } from '../sdam/server';
54
import type { ClientSession } from '../sessions';
@@ -10,6 +9,7 @@ import { Aspect, defineAspects, Hint } from './operation';
109

1110
/** @internal */
1211
export const DB_AGGREGATE_COLLECTION = 1 as const;
12+
const MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT = 8 as const;
1313

1414
/** @public */
1515
export interface AggregateOptions extends CommandOperationOptions {
@@ -91,11 +91,11 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {
9191
const serverWireVersion = maxWireVersion(server);
9292
const command: Document = { aggregate: this.target, pipeline: this.pipeline };
9393

94-
if (this.hasWriteStage && serverWireVersion < MONGODB_WIRE_VERSION.SHARDED_TRANSACTIONS) {
94+
if (this.hasWriteStage && serverWireVersion < MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT) {
9595
this.readConcern = undefined;
9696
}
9797

98-
if (serverWireVersion >= MONGODB_WIRE_VERSION.COMMANDS_ACCEPT_WRITE_CONCERN) {
98+
if (serverWireVersion >= 5) {
9999
if (this.hasWriteStage && this.writeConcern) {
100100
Object.assign(command, { writeConcern: this.writeConcern });
101101
}

0 commit comments

Comments
 (0)