Skip to content

Commit 239e9ad

Browse files
authored
Merge pull request #90 from athombv/fix/multiple-interfaces
Improvements in connection logic
2 parents 7ac464c + be61912 commit 239e9ad

3 files changed

Lines changed: 452 additions & 252 deletions

File tree

lib/KNXInterface.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const util = require('util');
77

88
class KNXInterface extends EventEmitter {
99

10-
constructor(knxInterface) {
10+
constructor(knxInterface, options = {}) {
1111
super();
1212

1313
// Setting object parameters from parameters from the interfacemanager
@@ -16,6 +16,11 @@ class KNXInterface extends EventEmitter {
1616
this.macAddress = knxInterface.interfaceMac;
1717
this.knxAddress = knxInterface.knxAddress;
1818

19+
// Resolver (from the interface manager) that maps the gateway IP to the local OS
20+
// interface name sharing its subnet. Re-run on every connect so a reboot that
21+
// reorders interfaces can't leave the tunnel bound to the wrong (V)LAN.
22+
this.getLocalInterfaceName = options.getLocalInterfaceName;
23+
1924
// KNX interface settings/variabeles
2025
this.isConnected = false; // Boolean to keep track of the connection status.
2126
this.isTimedOut = false; // Boolean to keep track of timeout events.
@@ -43,7 +48,13 @@ class KNXInterface extends EventEmitter {
4348
// The KNX tunnel connection itself through the knx library
4449
if (this.isConnected === true && !this.isTimedOut) return; // Skip re-initializing when already connected and healthy.
4550
try {
46-
this.knxConnection = new knx.Connection({
51+
// Resolve which local interface routes to this gateway. When it can't be
52+
// determined we omit the option so the knx lib keeps its default behaviour.
53+
const localInterface = typeof this.getLocalInterfaceName === 'function'
54+
? this.getLocalInterfaceName(this.ipAddress)
55+
: undefined;
56+
57+
const connectionOptions = {
4758
ipAddr: this.ipAddress, // IP address obtained through interfacemanager
4859
ipPort: 3671, // Fixed and part of the KNXnet/IP protocol.
4960
physAddr: this.knxAddress, // KNX address obtained through interfacemanager
@@ -90,7 +101,16 @@ class KNXInterface extends EventEmitter {
90101
this.log('Error from FSM:', connstatus);
91102
},
92103
},
93-
});
104+
};
105+
106+
// Bind to the interface on the gateway's subnet so the CONNECT_REQUEST HPAI
107+
// carries a routable source address (critical on multi-interface hosts/SHS).
108+
if (localInterface) {
109+
this.log(`Binding tunnel to local interface ${localInterface}`);
110+
connectionOptions.interface = localInterface;
111+
}
112+
113+
this.knxConnection = new knx.Connection(connectionOptions);
94114
} catch (error) {
95115
this.log('KNX lib error', error); // This should be able to catch the 'no valid ipv4 interfaces' error
96116
}

0 commit comments

Comments
 (0)