diff --git a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
index dcc8060d4..090a0e518 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
@@ -231,6 +231,12 @@ button.red-ui-tray-resize-button {
border: 1px solid var(--red-ui-secondary-border-color);
max-width: 450px;
}
+ .form-row > div.form-tips {
+ width: 70%;
+ display: inline-block;
+ box-sizing: border-box;
+ max-width: 350px; // 100 less for label width
+ }
.form-tips code {
border: none;
padding: auto;
diff --git a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html
index d967ca971..701db4e6e 100644
--- a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html
+++ b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html
@@ -23,6 +23,12 @@
+
+
+
@@ -70,7 +76,9 @@
color: "Silver",
defaults: {
name: {value:""},
- server: {value:"server", required:true},
+ server: {
+ value: RED.settings.tcpInAllowInboundConnections === false ? "client" : "server",
+ },
host: {
value:"",
validate:function(v, opt) {
@@ -107,8 +115,14 @@
var sockettype = $("#node-input-server").val();
if (sockettype == "client") {
$("#node-input-host-row").show();
+ $(".form-row.inbound-disabled-tip").addClass("hide")
} else {
$("#node-input-host-row").hide();
+ if(RED.settings.tcpInAllowInboundConnections === false) {
+ $(".form-row.inbound-disabled-tip").removeClass("hide")
+ } else {
+ $(".form-row.inbound-disabled-tip").addClass("hide")
+ }
}
var datamode = $("#node-input-datamode").val();
var datatype = $("#node-input-datatype").val();
@@ -142,6 +156,11 @@
$("#node-input-usetls").on("click",function() {
updateTLSOptions();
});
+ setTimeout(function() {
+ // form tips have a max-width to prevent the initial edit form size calc making it overly large.
+ // once the form is built and displayed, remove the size limit so that it sizes with the other elements.
+ $('.form-tips').css({"max-width": "unset"})
+ }, 500)
},
oneditsave: function() {
if (!$("#node-input-usetls").is(':checked')) {
@@ -162,7 +181,10 @@
-
+
@@ -242,16 +264,23 @@
$("#node-input-host-row").hide();
$("#node-input-end-row").hide();
$("#node-input-tls-enable").hide();
+ $(".form-row.inbound-disabled-tip").addClass("hide")
} else if (sockettype == "client"){
$("#node-input-port-row").show();
$("#node-input-host-row").show();
$("#node-input-end-row").show();
$("#node-input-tls-enable").show();
+ $(".form-row.inbound-disabled-tip").addClass("hide")
} else {
$("#node-input-port-row").show();
$("#node-input-host-row").hide();
$("#node-input-end-row").show();
$("#node-input-tls-enable").show();
+ if(RED.settings.tcpInAllowInboundConnections === false) {
+ $(".form-row.inbound-disabled-tip").removeClass("hide")
+ } else {
+ $(".form-row.inbound-disabled-tip").addClass("hide")
+ }
}
};
updateOptions();
@@ -272,6 +301,11 @@
$("#node-input-usetls").on("click",function() {
updateTLSOptions();
});
+ setTimeout(function() {
+ // form tips have a max-width to prevent the initial edit form size calc making it overly large.
+ // once the form is built and displayed, remove the size limit so that it sizes with the other elements.
+ $('.form-tips').css({"max-width": "unset"})
+ }, 500)
},
oneditsave: function() {
if (!$("#node-input-usetls").is(':checked')) {
diff --git a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
index 500bbe2c2..7fce37d37 100644
--- a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
+++ b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
@@ -19,6 +19,7 @@ module.exports = function(RED) {
let reconnectTime = RED.settings.socketReconnectTime || 10000;
let socketTimeout = RED.settings.socketTimeout || null;
const msgQueueSize = RED.settings.tcpMsgQueueSize || 1000;
+ const allowInbound = RED.settings.tcpInAllowInboundConnections === false ? false : true
const Denque = require('denque');
const net = require('net');
const tls = require('tls');
@@ -196,8 +197,7 @@ module.exports = function(RED) {
clearTimeout(reconnectTimeout);
if (!node.connected) { done(); }
});
- }
- else {
+ } else if (allowInbound) {
let srv = net;
let connOpts;
if (n.tls) {
@@ -308,9 +308,19 @@ module.exports = function(RED) {
});
}
});
+ } else {
+ node.warn(RED._("tcpin.status.inbound-disabled",{host:node.host,port:node.port}));
+ node.status({fill:"gray",shape:"circle",text:"tcpin.status.inbound-disabled"});
}
}
- RED.nodes.registerType("tcp in",TcpIn);
+ RED.nodes.registerType("tcp in",TcpIn, {
+ settings: {
+ tcpInAllowInboundConnections: {
+ value: true,
+ exportable: true
+ }
+ }
+ });
function TcpOut(n) {
@@ -444,7 +454,7 @@ module.exports = function(RED) {
nodeDone();
});
}
- else {
+ else if (allowInbound) {
const connectedSockets = new Set();
node.status({text:RED._("tcpin.status.connections",{count:0})});
let srv = net;
@@ -517,11 +527,13 @@ module.exports = function(RED) {
});
}
});
+ } else {
+ node.warn(RED._("tcpin.status.inbound-disabled",{host:node.host,port:node.port}));
+ node.status({fill:"gray",shape:"circle",text:"tcpin.status.inbound-disabled"});
}
}
RED.nodes.registerType("tcp out",TcpOut);
-
function TcpGet(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
diff --git a/packages/node_modules/@node-red/nodes/core/network/32-udp.html b/packages/node_modules/@node-red/nodes/core/network/32-udp.html
index 4d5eeb23e..f70cf973d 100644
--- a/packages/node_modules/@node-red/nodes/core/network/32-udp.html
+++ b/packages/node_modules/@node-red/nodes/core/network/32-udp.html
@@ -18,11 +18,15 @@
diff --git a/packages/node_modules/@node-red/nodes/core/network/32-udp.js b/packages/node_modules/@node-red/nodes/core/network/32-udp.js
index d42d3a7c3..e3b202182 100644
--- a/packages/node_modules/@node-red/nodes/core/network/32-udp.js
+++ b/packages/node_modules/@node-red/nodes/core/network/32-udp.js
@@ -16,9 +16,10 @@
module.exports = function(RED) {
"use strict";
- var os = require('os');
- var dgram = require('dgram');
- var udpInputPortsInUse = {};
+ const os = require('os');
+ const dgram = require('dgram');
+ const udpInputPortsInUse = {};
+ const allowInbound = RED.settings.udpInAllowInboundConnections === false ? false : true
// The Input Node
function UDPin(n) {
@@ -29,97 +30,102 @@ module.exports = function(RED) {
this.iface = n.iface || null;
this.multicast = n.multicast;
this.ipv = n.ipv || "udp4";
- var node = this;
-
- if (node.iface && node.iface.indexOf(".") === -1) {
- try {
- if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) {
- if (node.ipv === "udp4") {
- node.iface = (os.networkInterfaces())[node.iface][1].address;
- } else {
- node.iface = (os.networkInterfaces())[node.iface][0].address;
- }
- }
- else {
- if (node.ipv === "udp4") {
- node.iface = (os.networkInterfaces())[node.iface][0].address;
- } else {
- node.iface = (os.networkInterfaces())[node.iface][1].address;
- }
- }
- }
- catch(e) {
- node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface}));
- node.iface = null;
- }
- }
-
- var opts = {type:node.ipv, reuseAddr:true};
- if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
- var server;
-
- if (!udpInputPortsInUse.hasOwnProperty(node.port)) {
- server = dgram.createSocket(opts); // default to udp4
- server.bind(node.port, function() {
- if (node.multicast == "true") {
- server.setBroadcast(true);
- server.setMulticastLoopback(false);
- try {
- server.setMulticastTTL(128);
- server.addMembership(node.group,node.iface);
- if (node.iface) { node.status({text:n.iface+" : "+node.iface}); }
- node.log(RED._("udp.status.mc-group",{group:node.group}));
- } catch (e) {
- if (e.errno == "EINVAL") {
- node.error(RED._("udp.errors.bad-mcaddress"));
- } else if (e.errno == "ENODEV") {
- node.error(RED._("udp.errors.interface"));
+ const node = this;
+ let server;
+ if (allowInbound) {
+ if (node.iface && node.iface.indexOf(".") === -1) {
+ try {
+ if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) {
+ if (node.ipv === "udp4") {
+ node.iface = (os.networkInterfaces())[node.iface][1].address;
} else {
- node.error(RED._("udp.errors.error",{error:e.errno}));
+ node.iface = (os.networkInterfaces())[node.iface][0].address;
+ }
+ }
+ else {
+ if (node.ipv === "udp4") {
+ node.iface = (os.networkInterfaces())[node.iface][0].address;
+ } else {
+ node.iface = (os.networkInterfaces())[node.iface][1].address;
}
}
}
+ catch(e) {
+ node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface}));
+ node.iface = null;
+ }
+ }
+
+ let opts = {type:node.ipv, reuseAddr:true};
+ if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
+
+ if (!udpInputPortsInUse.hasOwnProperty(node.port)) {
+ server = dgram.createSocket(opts); // default to udp4
+ server.bind(node.port, function() {
+ if (node.multicast == "true") {
+ server.setBroadcast(true);
+ server.setMulticastLoopback(false);
+ try {
+ server.setMulticastTTL(128);
+ server.addMembership(node.group,node.iface);
+ if (node.iface) { node.status({text:n.iface+" : "+node.iface}); }
+ node.log(RED._("udp.status.mc-group",{group:node.group}));
+ } catch (e) {
+ if (e.errno == "EINVAL") {
+ node.error(RED._("udp.errors.bad-mcaddress"));
+ } else if (e.errno == "ENODEV") {
+ node.error(RED._("udp.errors.interface"));
+ } else {
+ node.error(RED._("udp.errors.error",{error:e.errno}));
+ }
+ }
+ }
+ });
+ udpInputPortsInUse[node.port] = server;
+ }
+ else {
+ node.log(RED._("udp.errors.alreadyused",{port:node.port}));
+ server = udpInputPortsInUse[node.port]; // re-use existing
+ if (node.iface) { node.status({text:n.iface+" : "+node.iface}); }
+ }
+
+ server.on("error", function (err) {
+ if ((err.code == "EACCES") && (node.port < 1024)) {
+ node.error(RED._("udp.errors.access-error"));
+ } else {
+ node.error(RED._("udp.errors.error",{error:err.code}));
+ }
+ server.close();
});
- udpInputPortsInUse[node.port] = server;
+
+ server.on('message', function (message, remote) {
+ let msg;
+ if (node.datatype =="base64") {
+ msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
+ } else if (node.datatype =="utf8") {
+ msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
+ } else {
+ msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
+ }
+ node.send(msg);
+ });
+
+ server.on('listening', function () {
+ const address = server.address();
+ node.log(RED._("udp.status.listener-at",{host:node.iface||address.address,port:address.port}));
+
+ });
+ } else {
+ node.warn(RED._("udp.status.inbound-disabled",{host:node.host,port:node.port}));
+ node.status({fill:"gray",shape:"circle",text:"udp.status.inbound-disabled"});
}
- else {
- node.log(RED._("udp.errors.alreadyused",{port:node.port}));
- server = udpInputPortsInUse[node.port]; // re-use existing
- if (node.iface) { node.status({text:n.iface+" : "+node.iface}); }
- }
-
- server.on("error", function (err) {
- if ((err.code == "EACCES") && (node.port < 1024)) {
- node.error(RED._("udp.errors.access-error"));
- } else {
- node.error(RED._("udp.errors.error",{error:err.code}));
- }
- server.close();
- });
-
- server.on('message', function (message, remote) {
- var msg;
- if (node.datatype =="base64") {
- msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
- } else if (node.datatype =="utf8") {
- msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
- } else {
- msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
- }
- node.send(msg);
- });
-
- server.on('listening', function () {
- var address = server.address();
- node.log(RED._("udp.status.listener-at",{host:node.iface||address.address,port:address.port}));
-
- });
-
node.on("close", function() {
try {
- if (node.multicast == "true") { server.dropMembership(node.group); }
- server.close();
- node.log(RED._("udp.status.listener-stopped"));
+ if (server) {
+ if (node.multicast == "true") { server.dropMembership(node.group); }
+ server.close();
+ node.log(RED._("udp.status.listener-stopped"));
+ }
} catch (err) {
//node.error(err);
}
@@ -133,7 +139,14 @@ module.exports = function(RED) {
RED.httpAdmin.get('/udp-ports/:id', RED.auth.needsPermission('udp-ports.read'), function(req,res) {
res.json(Object.keys(udpInputPortsInUse));
});
- RED.nodes.registerType("udp in",UDPin);
+ RED.nodes.registerType("udp in",UDPin, {
+ settings: {
+ udpInAllowInboundConnections: {
+ value: true,
+ exportable: true
+ }
+ }
+ });
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
index bc89992e2..219ec94f6 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
@@ -650,6 +650,9 @@
"never": "never - keep connection open",
"immed": "immediately - don't wait for reply"
},
+ "tip": {
+ "inbound-disabled": "inbound connections are disabled for this Node-RED instance"
+ },
"status": {
"connecting": "connecting to __host__:__port__",
"connected": "connected to __host__:__port__",
@@ -658,7 +661,8 @@
"connection-from": "connection from __host__:__port__",
"connection-closed": "connection closed from __host__:__port__",
"connections": "__count__ connection",
- "connections_plural": "__count__ connections"
+ "connections_plural": "__count__ connections",
+ "inbound-disabled": "inbound connections are disabled"
},
"errors": {
"connection-lost": "connection lost to __host__:__port__",
@@ -711,7 +715,8 @@
"tip": {
"in": "Tip: Make sure your firewall will allow the data in.",
"out": "Tip: leave address and port blank if you want to set using msg.ip
and msg.port
.",
- "port": "Ports already in use: "
+ "port": "Ports already in use: ",
+ "inbound-disabled": "inbound connections are disabled for this Node-RED instance"
},
"status": {
"listener-at": "udp listener at __host__:__port__",
@@ -722,7 +727,8 @@
"bc-ready": "udp broadcast ready: __outport__ -> __host__:__port__",
"ready": "udp ready: __outport__ -> __host__:__port__",
"ready-nolocal": "udp ready: __host__:__port__",
- "re-use": "udp re-use socket: __outport__ -> __host__:__port__"
+ "re-use": "udp re-use socket: __outport__ -> __host__:__port__",
+ "inbound-disabled": "inbound connections are disabled"
},
"errors": {
"access-error": "UDP access error, you may need root access for ports below 1024",
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html b/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html
index 708df0449..574891304 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html
@@ -16,9 +16,11 @@