Skip to content

Commit 3cc53cb

Browse files
authored
fix: ipv6 is not supported when using dns service discovery
Both server class and monitoring class split the address string on ":" and assumed it would return address and port tuple. To handle IPv6 addresses we need to use the number at the end of the address and keep the ipv6 address from being split. I consolidated the logic into ServerDescription getters. NODE-2671
1 parent 95440fb commit 3cc53cb

File tree

5 files changed

+27
-15
lines changed

5 files changed

+27
-15
lines changed

src/sdam/monitor.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ServerHeartbeatSucceededEvent,
1616
ServerHeartbeatFailedEvent
1717
} from './events';
18+
import { Server } from './server';
1819

1920
const kServer = Symbol('server');
2021
const kMonitorId = Symbol('monitorId');
@@ -47,7 +48,7 @@ class Monitor extends EventEmitter {
4748
[kCancellationToken]: any;
4849
[kMonitorId]: any;
4950

50-
constructor(server: any, options: any) {
51+
constructor(server: Server, options: any) {
5152
super(options);
5253
this[kServer] = server;
5354
this[kConnection] = undefined;
@@ -73,12 +74,11 @@ class Monitor extends EventEmitter {
7374
});
7475

7576
// TODO: refactor this to pull it directly from the pool, requires new ConnectionPool integration
76-
const addressParts = server.description.address.split(':');
7777
const connectOptions = Object.assign(
7878
{
7979
id: '<monitor>',
80-
host: addressParts[0],
81-
port: parseInt(addressParts[1], 10),
80+
host: server.description.host,
81+
port: server.description.port,
8282
connectionType: Connection
8383
},
8484
server.s.options,

src/sdam/server.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,7 @@ class Server extends EventEmitter {
102102

103103
// create the connection pool
104104
// NOTE: this used to happen in `connect`, we supported overriding pool options there
105-
const addressParts = this.description.address.split(':');
106-
const poolOptions = Object.assign(
107-
{ host: addressParts[0], port: parseInt(addressParts[1], 10) },
108-
options
109-
);
105+
const poolOptions = Object.assign({ host: description.host, port: description.port }, options);
110106

111107
this.s.pool = new ConnectionPool(poolOptions);
112108
relayEvents(
@@ -150,7 +146,7 @@ class Server extends EventEmitter {
150146
});
151147
}
152148

153-
get description() {
149+
get description(): ServerDescription {
154150
return this.s.description;
155151
}
156152

src/sdam/server_description.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const ISMASTER_FIELDS = [
4343
* Internal type, not meant to be directly instantiated
4444
*/
4545
class ServerDescription {
46-
address: any;
46+
address: string;
4747
error: any;
4848
roundTripTime: any;
4949
lastUpdateTime: any;
@@ -135,6 +135,16 @@ class ServerDescription {
135135
return WRITABLE_SERVER_TYPES.has(this.type);
136136
}
137137

138+
get host() {
139+
const chopLength = `:${this.port}`.length;
140+
return this.address.slice(0, -chopLength);
141+
}
142+
143+
get port() {
144+
const port = this.address.split(':').pop();
145+
return port ? Number.parseInt(port, 10) : port;
146+
}
147+
138148
/**
139149
* Determines if another `ServerDescription` is equal to this one per the rules defined
140150
* in the {@link https://github.com./mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#serverdescription|SDAM spec}

test/unit/sdam/monitoring.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ const { ServerType } = require('../../../src/sdam/common');
44
const { Topology } = require('../../../src/sdam/topology');
55
const { Monitor } = require('../../../src/sdam/monitor');
66
const { expect } = require('chai');
7+
const { ServerDescription } = require('../../../src/sdam/server_description');
78

89
class MockServer {
910
constructor(options) {
1011
this.s = {};
11-
this.description = {
12-
type: ServerType.Unknown,
13-
address: `${options.host}:${options.port}`
14-
};
12+
this.description = new ServerDescription(`${options.host}:${options.port}`);
13+
this.description.type = ServerType.Unknown;
1514
}
1615
}
1716

@@ -192,6 +191,7 @@ describe('monitoring', function() {
192191
});
193192

194193
const server = new MockServer(mockServer.address());
194+
server.description = new ServerDescription(server.description.address);
195195
const monitor = new Monitor(server, {
196196
heartbeatFrequencyMS: 250,
197197
minHeartbeatFrequencyMS: 50

test/unit/sdam/server_description.test.js

+6
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,10 @@ describe('ServerDescription', function() {
4141
});
4242
});
4343
});
44+
45+
it('should sensibly parse an ipv6 address', function() {
46+
const description = new ServerDescription('abcd:f::abcd:abcd:abcd:abcd:27017');
47+
expect(description.host).to.equal('abcd:f::abcd:abcd:abcd:abcd');
48+
expect(description.port).to.equal(27017);
49+
});
4450
});

0 commit comments

Comments
 (0)