Skip to content

Modify DNS Route when WAN port address is changed. #1472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions plugins/interface/intf_base_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -814,19 +814,53 @@ class InterfaceBasePlugin extends Plugin {
}

async updateRouteForDNS() {
await this._removeOldRouteForDNS();
const dns = await this.getDNSNameservers();
const gateway = await routing.getInterfaceGWIP(this.name, 4);
const gateway6 = await routing.getInterfaceGWIP(this.name, 6);
if (!_.isArray(dns) || dns.length === 0 || !gateway)
return;
for (const dnsIP of dns) {
if (new Address4(dnsIP).isValid())
await routing.addRouteToTable(dnsIP, gateway, this.name, `${this.name}_default`, null, 4, true).catch((err) => {});
await routing.addRouteToTable(dnsIP, gateway, this.name, `${this.name}_default`, null, 4, true)
.then(()=>{this._updateDnsRouteCache(dnsIP, gateway, this.name, `${this.name}_default`, 4);})
.catch((err) => {});
else
await routing.addRouteToTable(dnsIP, gateway6, this.name, `${this.name}_default`, null, 6, true).catch((err) => {});
await routing.addRouteToTable(dnsIP, gateway6, this.name, `${this.name}_default`, null, 6, true)
.then(()=>{this._updateDnsRouteCache(dnsIP, gateway6, this.name, `${this.name}_default`, 6);})
.catch((err) => {});
}
}

async _removeOldRouteForDNS() {
// remove Old DNS specific routes
if (_.isObject(this._dnsRoutes)) {
for (const inf of Object.keys(this._dnsRoutes)) {
for (const dnsRoute of this._dnsRoutes[inf]) {
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", dnsRoute.af).catch((err) => { });
}
}
}
this._dnsRoutes = {}
}

_updateDnsRouteCache(dnsIP, gw, viaIntf, tableName="main", af=4) {
if (!this._dnsRoutes){
this._dnsRoutes = {}
}
if (!this._dnsRoutes[viaIntf]) {
this._dnsRoutes[viaIntf] = [];
}
for (const dns of this._dnsRoutes[viaIntf]) {
if (dns.dest == dnsIP && dns.gw == gw && dns.viaIntf == viaIntf && dns.tableName == tableName) {
// ensure no duplicates
return;
}
}
this._dnsRoutes[viaIntf].push({dest: dnsIP, gw: gw, viaIntf: viaIntf, tableName: tableName, af:af});
}


async unmarkOutputConnection(rtid) {
if (_.isArray(this._srcIPs)) {
for (const ip4Addr of this._srcIPs) {
Expand Down
22 changes: 14 additions & 8 deletions plugins/routing/routing_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,23 @@ class RoutingPlugin extends Plugin {
if (!af || af == 4) {
// remove DNS specific routes
if (_.isObject(this._dnsRoutes)) {
for (const dnsRoute of Object.keys(this._dnsRoutes).map(key => this._dnsRoutes[key]).filter(i => i.af == 4))
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", dnsRoute.af).catch((err) => { });
this._dnsRoutes = Object.entries(this._dnsRoutes).reduce((routes, item) => { if (item[1].af == 6) routes[item[0]] = item[1]; return routes }, {});
for (const inf of Object.keys(this._dnsRoutes)) {
for (const dnsRoute of this._dnsRoutes[inf].filter(i => i.af == 4)) {
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", dnsRoute.af).catch((err) => { });
}
this._dnsRoutes[inf] = this._dnsRoutes[inf].filter(i => i.af != 4);
}
} else { this._dnsRoutes = {} }
}
if (!af || af == 6) {
// remove DNS specific routes
if (_.isObject(this._dnsRoutes)) {
for (const dnsRoute of Object.keys(this._dnsRoutes).map(key => this._dnsRoutes[key]).filter(i => i.af == 6))
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", dnsRoute.af).catch((err) => { });
this._dnsRoutes = Object.entries(this._dnsRoutes).reduce((routes, item) => { if (item[1].af != 6) routes[item[0]] = item[1]; return routes }, {});
for (const inf of Object.keys(this._dnsRoutes)) {
for (const dnsRoute of this._dnsRoutes[inf].filter(i => i.af == 6)) {
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", dnsRoute.af).catch((err) => { });
}
this._dnsRoutes[inf] = this._dnsRoutes[inf].filter(i => i.af != 6);
}
} else {this._dnsRoutes = {}}
}
break;
Expand Down Expand Up @@ -541,8 +547,8 @@ class RoutingPlugin extends Plugin {
await this.upsertRouteToTable(dns6IP, gw6, viaIntf, routing.RT_GLOBAL_DEFAULT, metric, 6).catch((err) => {
this.log.error(`Failed to add route ipv6 to ${routing.RT_GLOBAL_DEFAULT} for dns ${dns6IP} via ${gw6} dev ${viaIntf}`, err.message);
});
// update all dns routes via the same interface but with new metrics in main table
await this.upsertRouteToTable(dns6IP, gw6, viaIntf, "main", metric, 6).then(() => {
// update all dns routes via the same interface but with new metrics in main table
await this.upsertRouteToTable(dns6IP, gw6, viaIntf, "main", metric, 6).then(() => {
this._updateDnsRouteCache(dns6IP, gw6, viaIntf, metric, "main", 6);
}).catch((err) => {
this.log.error(`Failed to add route to main for dns ${dns6IP} via ${gw6} dev ${viaIntf}`, err.message);
Expand Down