node-firebird 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/0001-fix-attachEvent-host-resolution.patch +72 -0
- package/diff +62 -0
- package/lib/wire/database.js +6 -1
- package/package.json +1 -1
- package/srp.js +0 -94
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
2
|
+
From: Gobbo89 <gobbo89@users.noreply.github.com>
|
|
3
|
+
Date: Thu, 19 Feb 2026 00:00:00 +0000
|
|
4
|
+
Subject: [PATCH] fix(events): resolve event channel host from connection options
|
|
5
|
+
|
|
6
|
+
When Firebird is configured with RemoteBindAddress unset (default),
|
|
7
|
+
auxConnection() returns socket_info.host = "0.0.0.0", which is a
|
|
8
|
+
bind-any address and not a routable destination for remote clients.
|
|
9
|
+
|
|
10
|
+
This commit changes the host selection logic in attachEvent to prefer
|
|
11
|
+
connection.options.host (the address that the user explicitly provided
|
|
12
|
+
and that is proven reachable, since the initial DB attach succeeded).
|
|
13
|
+
|
|
14
|
+
Only if options.host is absent does it fall back to socket_info.host,
|
|
15
|
+
and even then only when that host is a concrete routable address (i.e.
|
|
16
|
+
not "0.0.0.0" and not "::"). As a last resort it uses the socket's
|
|
17
|
+
remoteAddress, normalizing IPv6-mapped IPv4 (::ffff:x.x.x.x → x.x.x.x).
|
|
18
|
+
|
|
19
|
+
Fixes #386.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
lib/wire/database.js | 25 +++++++++++++++++++++++--
|
|
23
|
+
1 file changed, 23 insertions(+), 2 deletions(-)
|
|
24
|
+
|
|
25
|
+
diff --git a/lib/wire/database.js b/lib/wire/database.js
|
|
26
|
+
index xxxxxxx..yyyyyyy 100644
|
|
27
|
+
--- a/lib/wire/database.js
|
|
28
|
+
+++ b/lib/wire/database.js
|
|
29
|
+
@@ -1,3 +1,18 @@
|
|
30
|
+
+/**
|
|
31
|
+
+ * Resolves the host to use for the auxiliary event channel.
|
|
32
|
+
+ *
|
|
33
|
+
+ * Priority:
|
|
34
|
+
+ * 1. connection.options.host – explicitly provided by the caller; known reachable.
|
|
35
|
+
+ * 2. socket_info.host – only when it is a concrete routable address
|
|
36
|
+
+ * (i.e. not "0.0.0.0" and not "::").
|
|
37
|
+
+ * 3. socket.remoteAddress – the OS-level address of the main connection socket,
|
|
38
|
+
+ * with IPv6-mapped IPv4 prefixes stripped.
|
|
39
|
+
+ *
|
|
40
|
+
+ * @param {object} connection The active database connection object.
|
|
41
|
+
+ * @param {string} auxHost The host returned by the auxConnection() call.
|
|
42
|
+
+ * @returns {string} A connectable host string.
|
|
43
|
+
+ */
|
|
44
|
+
+function resolveEventHost(connection, auxHost) {
|
|
45
|
+
+ // 1. Prefer the host the caller explicitly supplied.
|
|
46
|
+
+ if (connection.options && connection.options.host) {
|
|
47
|
+
+ return connection.options.host;
|
|
48
|
+
+ }
|
|
49
|
+
+
|
|
50
|
+
+ // 2. Use auxConnection host only when it is a real address.
|
|
51
|
+
+ var BIND_ANY = ['0.0.0.0', '::'];
|
|
52
|
+
+ if (auxHost && BIND_ANY.indexOf(auxHost) === -1) {
|
|
53
|
+
+ return auxHost;
|
|
54
|
+
+ }
|
|
55
|
+
+
|
|
56
|
+
+ // 3. Fall back to the OS-reported remote address of the main socket,
|
|
57
|
+
+ // normalising IPv6-mapped IPv4 (e.g. "::ffff:10.0.0.1" → "10.0.0.1").
|
|
58
|
+
+ var remoteAddress = connection._socket && connection._socket.remoteAddress;
|
|
59
|
+
+ if (remoteAddress) {
|
|
60
|
+
+ return remoteAddress.replace(/^::ffff:/, '');
|
|
61
|
+
+ }
|
|
62
|
+
+
|
|
63
|
+
+ // Last resort: return whatever auxConnection gave us and let the caller fail
|
|
64
|
+
+ // with a meaningful socket error rather than a silent undefined.
|
|
65
|
+
+ return auxHost;
|
|
66
|
+
+}
|
|
67
|
+
+
|
|
68
|
+
// ... (existing code) ...
|
|
69
|
+
|
|
70
|
+
- var eventConnection = new EventConnection(socket_info.host, socket_info.port, self.connection.options, eventCallback);
|
|
71
|
+
+ var eventHost = resolveEventHost(self.connection, socket_info.host);
|
|
72
|
+
+ var eventConnection = new EventConnection(eventHost, socket_info.port, self.connection.options, eventCallback);
|
package/diff
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
diff --git a/lib/wire/database.js b/lib/wire/database.js
|
|
2
|
+
index d91b9db..a9f3128 100644
|
|
3
|
+
--- a/lib/wire/database.js
|
|
4
|
+
+++ b/lib/wire/database.js
|
|
5
|
+
@@ -5,6 +5,46 @@ const Const = require('./const');
|
|
6
|
+
const EventConnection = require('./eventConnection');
|
|
7
|
+
const FbEventManager = require('./fbEventManager');
|
|
8
|
+
|
|
9
|
+
+/**
|
|
10
|
+
+ * Resolves the host to use for the auxiliary event channel.
|
|
11
|
+
+ *
|
|
12
|
+
+ * Priority:
|
|
13
|
+
+ * 1. connection.options.host – explicitly provided by the caller; known reachable.
|
|
14
|
+
+ * 2. socket_info.host – only when it is a concrete routable address
|
|
15
|
+
+ * (i.e. not "0.0.0.0" and not "::").
|
|
16
|
+
+ * 3. socket.remoteAddress – the OS-level address of the main connection socket,
|
|
17
|
+
+ * with IPv6-mapped IPv4 prefixes stripped.
|
|
18
|
+
+ *
|
|
19
|
+
+ * @param {object} connection The active database connection object.
|
|
20
|
+
+ * @param {string} auxHost The host returned by the auxConnection() call.
|
|
21
|
+
+ * @returns {string} A connectable host string.
|
|
22
|
+
+ */
|
|
23
|
+
+function resolveEventHost(connection, auxHost) {
|
|
24
|
+
+ // 1. Prefer the host the caller explicitly supplied.
|
|
25
|
+
+ if (connection.options && connection.options.host) {
|
|
26
|
+
+ return connection.options.host;
|
|
27
|
+
+ }
|
|
28
|
+
+
|
|
29
|
+
+ // 2. Use auxConnection host only when it is a real address.
|
|
30
|
+
+ var BIND_ANY = ['0.0.0.0', '::'];
|
|
31
|
+
+ if (auxHost && BIND_ANY.indexOf(auxHost) === -1) {
|
|
32
|
+
+ return auxHost;
|
|
33
|
+
+ }
|
|
34
|
+
+
|
|
35
|
+
+ // 3. Fall back to the OS-reported remote address of the main socket,
|
|
36
|
+
+ // normalising IPv6-mapped IPv4 (e.g. "::ffff:10.0.0.1" → "10.0.0.1").
|
|
37
|
+
+ var remoteAddress = connection._socket && connection._socket.remoteAddress;
|
|
38
|
+
+ if (remoteAddress) {
|
|
39
|
+
+ return remoteAddress.replace(/^::ffff:/, '');
|
|
40
|
+
+ }
|
|
41
|
+
+
|
|
42
|
+
+ // Last resort: return whatever auxConnection gave us and let the caller fail
|
|
43
|
+
+ // with a meaningful socket error rather than a silent undefined.
|
|
44
|
+
+ return auxHost;
|
|
45
|
+
+}
|
|
46
|
+
+
|
|
47
|
+
+
|
|
48
|
+
+
|
|
49
|
+
/***************************************
|
|
50
|
+
*
|
|
51
|
+
* Database
|
|
52
|
+
@@ -279,8 +319,9 @@ class Database extends Events.EventEmitter {
|
|
53
|
+
doError(err, callback);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
+ var eventHost = resolveEventHost(self.connection, socket_info.host);
|
|
57
|
+
|
|
58
|
+
- const eventConnection = new EventConnection(socket_info.host, socket_info.port, function (err) {
|
|
59
|
+
+ const eventConnection = new EventConnection(eventHost, socket_info.port, function (err) {
|
|
60
|
+
if (err) {
|
|
61
|
+
doError(err, callback);
|
|
62
|
+
return;
|
package/lib/wire/database.js
CHANGED
|
@@ -280,7 +280,12 @@ class Database extends Events.EventEmitter {
|
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
const
|
|
283
|
+
const host = (socket_info.host === '0.0.0.0' || socket_info.host === '::')
|
|
284
|
+
? self.connection.options.host
|
|
285
|
+
: socket_info.host;
|
|
286
|
+
|
|
287
|
+
const eventConnection = new EventConnection(
|
|
288
|
+
host, socket_info.port, function(err) {
|
|
284
289
|
if (err) {
|
|
285
290
|
doError(err, callback);
|
|
286
291
|
return;
|
package/package.json
CHANGED
package/srp.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const BigInteger = require('big-integer');
|
|
2
|
-
const crypto = require('crypto');
|
|
3
|
-
|
|
4
|
-
console.log('Preparing benchmark...');
|
|
5
|
-
|
|
6
|
-
// Constants from lib/srp.js
|
|
7
|
-
const HEX_N = 'E67D2E994B2F900C3F41F08F5BB2627ED0D49EE1FE767A52EFCD565CD6E768812C3E1E9CE8F0A8BEA6CB13CD29DDEBF7A96D4A93B55D488DF099A15C89DCB0640738EB2CBDD9A8F7BAB561AB1B0DC1C6CDABF303264A08D1BCA932D1F1EE428B619D970F342ABA9A65793B8B2F041AE5364350C16F735F56ECBCA87BD57B29E7';
|
|
8
|
-
const DEC_K = '1277432915985975349439481660349303019122249719989';
|
|
9
|
-
|
|
10
|
-
// --- Library Setup ---
|
|
11
|
-
const lib_N = BigInteger(HEX_N, 16);
|
|
12
|
-
const lib_g = BigInteger(2);
|
|
13
|
-
const lib_k = BigInteger(DEC_K);
|
|
14
|
-
|
|
15
|
-
// --- Native Setup ---
|
|
16
|
-
const native_N = BigInt('0x' + HEX_N);
|
|
17
|
-
const native_g = 2n;
|
|
18
|
-
const native_k = BigInt(DEC_K);
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Native BigInt Modular Exponentiation
|
|
22
|
-
* Calculates (base ^ exp) % mod
|
|
23
|
-
*/
|
|
24
|
-
function nativeModPow(base, exp, mod) {
|
|
25
|
-
let result = 1n;
|
|
26
|
-
base = base % mod;
|
|
27
|
-
while (exp > 0n) {
|
|
28
|
-
if (exp & 1n) result = (result * base) % mod;
|
|
29
|
-
base = (base * base) % mod;
|
|
30
|
-
exp >>= 1n;
|
|
31
|
-
}
|
|
32
|
-
return result;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// --- Test Data Generation ---
|
|
36
|
-
const ITERATIONS = 2000;
|
|
37
|
-
const inputs = [];
|
|
38
|
-
|
|
39
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
40
|
-
// Generate random 32-byte private key (similar to SRP_KEY_SIZE)
|
|
41
|
-
const hex = crypto.randomBytes(32).toString('hex');
|
|
42
|
-
inputs.push({
|
|
43
|
-
lib: BigInteger(hex, 16),
|
|
44
|
-
native: BigInt('0x' + hex)
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// --- Verification ---
|
|
49
|
-
console.log('Verifying implementations match...');
|
|
50
|
-
const vLib = lib_g.modPow(inputs[0].lib, lib_N);
|
|
51
|
-
const vNative = nativeModPow(native_g, inputs[0].native, native_N);
|
|
52
|
-
|
|
53
|
-
if (vLib.toString(16) !== vNative.toString(16)) {
|
|
54
|
-
console.error('MISMATCH!');
|
|
55
|
-
console.error('Lib:', vLib.toString(16));
|
|
56
|
-
console.error('Nat:', vNative.toString(16));
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
console.log('Verification passed.');
|
|
60
|
-
|
|
61
|
-
// --- Benchmark ---
|
|
62
|
-
console.log(`\nStarting benchmark (${ITERATIONS} iterations)...`);
|
|
63
|
-
|
|
64
|
-
// 1. Library Benchmark
|
|
65
|
-
const startLib = process.hrtime.bigint();
|
|
66
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
67
|
-
// Simulate: A = g^a % N
|
|
68
|
-
const A = lib_g.modPow(inputs[i].lib, lib_N);
|
|
69
|
-
|
|
70
|
-
// Simulate part of server calc: B = (k*v + g^b) % N
|
|
71
|
-
// We'll just do (k * A) % N + A to simulate the mix of mult/add/mod
|
|
72
|
-
const term = lib_k.multiply(A).mod(lib_N).add(A).mod(lib_N);
|
|
73
|
-
}
|
|
74
|
-
const endLib = process.hrtime.bigint();
|
|
75
|
-
|
|
76
|
-
// 2. Native Benchmark
|
|
77
|
-
const startNative = process.hrtime.bigint();
|
|
78
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
79
|
-
// Simulate: A = g^a % N
|
|
80
|
-
const A = nativeModPow(native_g, inputs[i].native, native_N);
|
|
81
|
-
|
|
82
|
-
// Simulate part of server calc: B = (k*v + g^b) % N
|
|
83
|
-
const term = ((native_k * A) % native_N + A) % native_N;
|
|
84
|
-
}
|
|
85
|
-
const endNative = process.hrtime.bigint();
|
|
86
|
-
|
|
87
|
-
// --- Results ---
|
|
88
|
-
const timeLib = Number(endLib - startLib) / 1e6; // ms
|
|
89
|
-
const timeNative = Number(endNative - startNative) / 1e6; // ms
|
|
90
|
-
|
|
91
|
-
console.log('\nResults:');
|
|
92
|
-
console.log(`big-integer (Lib): ${timeLib.toFixed(2)} ms`);
|
|
93
|
-
console.log(`Native BigInt: ${timeNative.toFixed(2)} ms`);
|
|
94
|
-
console.log(`\nSpeedup: ${(timeLib / timeNative).toFixed(2)}x faster`);
|