Add igd/no igd setting

This commit is contained in:
everoddandeven 2024-12-26 15:17:04 +01:00
parent 5717f2e43b
commit 5813c56649
9 changed files with 119 additions and 15 deletions

View file

@ -526,6 +526,22 @@
<div class="col-md-12 col-lg-12">
<h4 class="mb-3">General</h4>
<div class="row gy-3">
<div class="form-check form-switch col-md-6">
<label for="no-igd" class="form-check-label">No IGD</label>
<input class="form-control form-check-input" type="checkbox" role="switch" id="no-igd" [checked]="currentSettings.noIgd" [(ngModel)]="currentSettings.noIgd" [ngModelOptions]="{standalone: true}">
<br>
<small class="text-body-secondary">Disable UPnP port mapping on the router (<strong>Internet Gateway Device</strong>). Enable this option to improve security if you are not behind a NAT (you can bind directly to public IP or you run through Tor)</small>
</div>
<div class="col-md-4">
<label for="igd" class="form-label">IGD</label>
<select [disabled]="currentSettings.noIgd" class="form-select" id="igd" [(ngModel)]="currentSettings.igd" [ngModelOptions]="{standalone: true}">
<option [ngValue]="'delayed'" [selected]="currentSettings.igd === 'delayed'">Delayed</option>
<option [ngValue]="'enabled'" [selected]="currentSettings.igd === 'enabled'">Enabled</option>
<option [ngValue]="'disabled'" [selected]="currentSettings.igd === 'disabled'">Disabled</option>
</select>
</div>
<div class="form-check form-switch col-md-6">
<label for="allow-local-ip" class="form-check-label">Allow local IP</label>

View file

@ -3,7 +3,7 @@ import { NavbarLink } from '../../shared/components/navbar/navbar.model';
import { DaemonSettings } from '../../../common/DaemonSettings';
import { DaemonService } from '../../core/services/daemon/daemon.service';
import { ElectronService } from '../../core/services';
import { InvalidDaemonSettingsKeyError } from '../../../common';
import { DaemonSettingsError, DaemonSettingsUnknownKeyError } from '../../../common';
@Component({
selector: 'app-settings',
@ -308,13 +308,13 @@ export class SettingsComponent {
this.successMessage = 'Succesfully imported settings';
}
catch(error: any) {
console.error(error);
this.successMessage = '';
if (error instanceof InvalidDaemonSettingsKeyError) {
if (error instanceof DaemonSettingsError) {
throw error;
}
console.error(error);
throw new Error("Could not parse monerod config file");
}
}

View file

@ -1,4 +1,4 @@
import { DaemonSettingsInvalidNetworkError, InvalidDaemonSettingsKeyError } from "./error";
import { DaemonSettingsDuplicateExclusiveNodeError, DaemonSettingsDuplicatePriorityNodeError, DaemonSettingsInvalidNetworkError, DaemonSettingsInvalidValueError, DaemonSettingsUnknownKeyError } from "./error";
export class DaemonSettings {
public monerodPath: string = '';
@ -92,8 +92,10 @@ export class DaemonSettings {
public p2pExternalPort: number = 0;
public allowLocalIp: boolean = false;
public addPeer: string = '';
public addPriorityNode: string = '';
public addExclusiveNode: string = '';
//public addPriorityNode: string = '';
//public addExclusiveNode: string = '';
public exlusiveNodes: string[] = [];
public priorityNodes: string[] = [];
public seedNode: string = '';
public txProxy: string = '';
@ -106,7 +108,7 @@ export class DaemonSettings {
public enableDnsBlocklist: boolean = false;
public noIgd: boolean = false;
public igd: 'disable' | 'enabled' | 'delayed' = 'delayed';
public igd: 'disabled' | 'enabled' | 'delayed' = 'delayed';
public outPeers: number = -1;
public inPeers: number = -1;
public tosFlag: number = -1;
@ -152,6 +154,38 @@ export class DaemonSettings {
return this.banList.split('\n');
}
public get hasExclusiveNodes(): boolean {
return this.exlusiveNodes.length > 0;
}
public get hasPriorityNodes(): boolean {
return this.priorityNodes.length > 0;
}
public addExclusiveNode(node: string): void {
if (this.exlusiveNodes.includes(node)) {
throw new DaemonSettingsDuplicateExclusiveNodeError(node);
}
this.exlusiveNodes.push(node);
}
public removeExclusiveNode(node: string): void {
this.exlusiveNodes = this.exlusiveNodes.filter((n) => n !== node);
}
public addPriorityNode(node: string): void {
if (this.priorityNodes.includes(node)) {
throw new DaemonSettingsDuplicatePriorityNodeError(node);
}
this.exlusiveNodes.push(node);
}
public removePriorityNode(node: string): void {
this.priorityNodes = this.priorityNodes.filter((n) => n !== node);
}
public assertValid(): void {
if (this.upgradeAutomatically && this.downloadUpgradePath == '') {
throw new Error('You must set a download path for monerod updates when enabling automatic upgrade');
@ -255,6 +289,14 @@ export class DaemonSettings {
case 'max-log-files': settings.maxLogFileSize = parseInt(value, 10); break;
case 'max-log-file-size': settings.maxLogFileSize = parseInt(value, 10); break;
case 'no-igd': settings.noIgd = boolValue; break;
case `igd`: {
if (value === 'enabled' || value === 'disabled' || value === 'delayed') {
settings.igd = value; break;
}
else {
throw new DaemonSettingsInvalidValueError(key, value);
}
}
case 'enable-dns-blocklist': settings.enableDnsBlocklist = boolValue; break;
case 'testnet': settings.testnet = boolValue; break;
case 'mainnet': settings.mainnet = boolValue; break;
@ -273,7 +315,7 @@ export class DaemonSettings {
case 'p2p-ignore-ipv4': settings.p2pIgnoreIpv4 = boolValue; break;
case 'p2p-external-port': settings.p2pExternalPort = parseInt(value, 10); break;
case 'add-peer': settings.addPeer = value; break;
case 'add-priority-node': settings.addPriorityNode = value; break;
case 'add-priority-node': settings.addPriorityNode(value); break;
case 'bootstrap-daemon-address': settings.bootstrapDaemonAddress = value; break;
case 'bootstrap-daemon-login': settings.bootstrapDaemonLogin = value; break;
case 'bootstrap-daemon-proxy': settings.bootstrapDaemonProxy = value; break;
@ -329,7 +371,7 @@ export class DaemonSettings {
case 'prune-blockchain': settings.pruneBlockchain = boolValue; break;
case 'keep-alt-blocks': settings.keepAltBlocks = boolValue; break;
case 'keep-fakechain': settings.keepFakeChain = boolValue; break;
case 'add-exclusive-node': settings.addExclusiveNode = value; break;
case 'add-exclusive-node': settings.addExclusiveNode(value); break;
case 'no-sync': settings.noSync = boolValue; break;
case 'start-mining': settings.startMining = value; break;
case 'mining-threads': settings.miningThreads = parseInt(value, 10); break;
@ -345,8 +387,7 @@ export class DaemonSettings {
case 'test-dbg-lock-sleep': settings.testDbgLockSleep = parseInt(value, 10); break;
case 'in-peers': settings.inPeers = parseInt(value, 10); break;
case 'out-peers': settings.outPeers = parseInt(value, 10); break;
default: throw new InvalidDaemonSettingsKeyError(key);
default: throw new DaemonSettingsUnknownKeyError(key);
}
});
@ -430,8 +471,8 @@ export class DaemonSettings {
if (this.p2pExternalPort > 0) options.push(`--p2p-external-port`, `${this.p2pExternalPort}`);
if (this.allowLocalIp) options.push(`--allow-local-ip`);
if (this.addPeer != '') options.push('--add-peer', this.addPeer);
if (this.addPriorityNode != '') options.push(`--add-priority-node`, this.addPriorityNode);
if (this.addExclusiveNode != '') options.push(`--add-exlcusive-node`, this.addExclusiveNode);
if (this.hasPriorityNodes) this.priorityNodes.forEach((node) => options.push(`--add-priority-node`, node));
if (this.hasExclusiveNodes) this.exlusiveNodes.forEach((node) => options.push(`--add-exlcusive-node`, node));
if (this.seedNode != '') options.push(`--seed-node`, this.seedNode);
if (this.txProxy != '') options.push(`--tx-proxy`, this.txProxy);
if (this.anonymousInbound != '') options.push(`--anonymous-inbound`, this.anonymousInbound);
@ -440,6 +481,7 @@ export class DaemonSettings {
if (this.noSync) options.push(`--no-sync`);
if (this.enableDnsBlocklist) options.push(`--enable-dns-blocklist`);
if (this.noIgd) options.push(`--no-igd`);
if (!this.noIgd && this.igd) options.push(`--igd`, this.igd);
if (this.outPeers >= 0) options.push(`--out-peers`, `${this.outPeers}`);
if (this.inPeers >= 0) options.push(`--in-peers`, `${this.inPeers}`);
if (this.tosFlag >= 0) options.push(`--tos-flag`, `${this.tosFlag}`);

View file

@ -0,0 +1,8 @@
import { DaemonSettingsDuplicateNodeError } from "./DaemonSettingsDuplicateNodeError";
export class DaemonSettingsDuplicateExclusiveNodeError extends DaemonSettingsDuplicateNodeError {
constructor(node: string) {
super(node, "exclusive");
}
}

View file

@ -0,0 +1,13 @@
import { DaemonSettingsError } from "./DaemonSettingsError";
export abstract class DaemonSettingsDuplicateNodeError extends DaemonSettingsError {
public node: string;
public type: string;
constructor(node: string, type: string) {
super(`${type} node ${node} already added`);
this.node = node;
this.type = type;
}
}

View file

@ -0,0 +1,8 @@
import { DaemonSettingsDuplicateNodeError } from "./DaemonSettingsDuplicateNodeError";
export class DaemonSettingsDuplicatePriorityNodeError extends DaemonSettingsDuplicateNodeError {
constructor(node: string) {
super(node, "priority");
}
}

View file

@ -0,0 +1,13 @@
import { DaemonSettingsError } from "./DaemonSettingsError"
export class DaemonSettingsInvalidValueError extends DaemonSettingsError {
public key: string;
public value: string;
constructor(key: string, value: string) {
super(`Invalid value <strong>${value}</strong> for daemon setting <strong>${key}</strong>`);
this.key = key;
this.value = value;
}
}

View file

@ -1,6 +1,6 @@
import { DaemonSettingsError } from "./DaemonSettingsError"
export class DaemonSettingsUnkownKeyError extends DaemonSettingsError {
export class DaemonSettingsUnknownKeyError extends DaemonSettingsError {
public key: string;
constructor(key: string) {

View file

@ -2,5 +2,9 @@ export { RpcError } from "./RpcError";
export { CoreIsBusyError } from "./CoreIsBusyError";
export { DaemonSettingsError } from "./DaemonSettingsError";
export { DaemonSettingsInvalidNetworkError } from "./DaemonSettingsInvalidNetworkError";
export { DaemonSettingsUnkownKeyError as InvalidDaemonSettingsKeyError } from "./DaemonSettingsUnknownKeyError";
export { DaemonSettingsInvalidValueError } from "./DaemonSettingsInvalidValueError";
export { DaemonSettingsUnknownKeyError } from "./DaemonSettingsUnknownKeyError";
export { DaemonSettingsDuplicateNodeError } from "./DaemonSettingsDuplicateNodeError";
export { DaemonSettingsDuplicateExclusiveNodeError } from "./DaemonSettingsDuplicateExclusiveNodeError";
export { DaemonSettingsDuplicatePriorityNodeError } from "./DaemonSettingsDuplicatePriorityNodeError";
export { MethodNotFoundError } from "./MethodNotFoundError";