Skip to content
46 changes: 40 additions & 6 deletions src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { createNTLMRequest } from './ntlm';
import { ColumnEncryptionAzureKeyVaultProvider } from './always-encrypted/keystore-provider-azure-key-vault';

import { AbortController, AbortSignal } from 'node-abort-controller';
import AbortError from './errors/abort-error';
Comment thread
MichaelSun90 marked this conversation as resolved.
Outdated
import { Parameter, TYPES } from './data-type';
import { BulkLoadPayload } from './bulk-load-payload';
import { Collation } from './collation';
Expand Down Expand Up @@ -2008,7 +2009,11 @@ class Connection extends EventEmitter {
this.transitionTo(this.STATE.SENT_PRELOGIN);
}

wrapWithTls(socket: net.Socket): Promise<tls.TLSSocket> {
wrapWithTls(socket: net.Socket, signal: AbortSignal): Promise<tls.TLSSocket> {
if (signal.aborted) {
throw new AbortError();
}
Comment thread
MichaelSun90 marked this conversation as resolved.
Outdated

return new Promise((resolve, reject) => {
const secureContext = tls.createSecureContext(this.secureContextOptions);
// If connect to an ip address directly,
Expand All @@ -2023,12 +2028,41 @@ class Connection extends EventEmitter {
servername: this.config.options.serverName ? this.config.options.serverName : serverName,
};

const encryptsocket = tls.connect(encryptOptions, () => {
encryptsocket.removeListener('error', reject);
const encryptsocket = tls.connect(encryptOptions);

const onAbort = () => {
encryptsocket.removeListener('error', onError);
encryptsocket.removeListener('connect', onConnect);

encryptsocket.destroy();

reject(new AbortError());
Comment thread
MichaelSun90 marked this conversation as resolved.
Outdated
};

const onError = (err: Error) => {
signal.removeEventListener('abort', onAbort);

encryptsocket.removeListener('error', onError);
encryptsocket.removeListener('connect', onConnect);

encryptsocket.destroy();

reject(err);
};

const onConnect = () => {
signal.removeEventListener('abort', onAbort);

encryptsocket.removeListener('error', onError);
encryptsocket.removeListener('connect', onConnect);

resolve(encryptsocket);
});
};

signal.addEventListener('abort', onAbort, { once: true });

encryptsocket.once('error', reject);
encryptsocket.on('error', onError);
encryptsocket.on('secureConnect', onConnect);
});
}

Expand All @@ -2047,7 +2081,7 @@ class Connection extends EventEmitter {
if (this.config.options.encrypt === 'strict') {
try {
// Wrap the socket with TLS for TDS 8.0
socket = await this.wrapWithTls(socket);
socket = await this.wrapWithTls(socket, signal);
} catch (err) {
socket.end();

Expand Down
4 changes: 2 additions & 2 deletions test/integration/connection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,12 @@ describe('Encrypt Test', function() {
return callback(err);
}

if (!productMajorVersion || productMajorVersion < '2022') {
if (!productMajorVersion || productMajorVersion < '16') {
connection.close();
return callback(null, false);
}

if (productMajorVersion > '2022') {
if (productMajorVersion > '16') {
connection.close();
return callback(null, true);
}
Expand Down