From bdc860be9f4c9ce32f523e355ea94532b0dbc1fa Mon Sep 17 00:00:00 2001 From: Florian Reimair Date: Wed, 27 Feb 2019 13:29:49 +0100 Subject: [PATCH 1/3] Optimized memory footprint of DoS protection --- .../bisq/network/p2p/network/Connection.java | 65 +++++++------------ 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/p2p/src/main/java/bisq/network/p2p/network/Connection.java b/p2p/src/main/java/bisq/network/p2p/network/Connection.java index d33a49fefc4..3b1851a5a69 100644 --- a/p2p/src/main/java/bisq/network/p2p/network/Connection.java +++ b/p2p/src/main/java/bisq/network/p2p/network/Connection.java @@ -43,7 +43,6 @@ import bisq.common.proto.ProtobufferException; import bisq.common.proto.network.NetworkEnvelope; import bisq.common.proto.network.NetworkProtoResolver; -import bisq.common.util.Tuple2; import bisq.common.util.Utilities; import io.bisq.generated.protobuffer.PB; @@ -77,7 +76,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; import java.lang.ref.WeakReference; @@ -162,7 +160,7 @@ public static int getPermittedMessageSize() { private PeerType peerType = PeerType.PEER; @Getter private final ObjectProperty peersNodeAddressProperty = new SimpleObjectProperty<>(); - private final List> messageTimeStamps = new ArrayList<>(); + private final List messageTimeStamps = new ArrayList<>(); private final CopyOnWriteArraySet messageListeners = new CopyOnWriteArraySet<>(); private volatile long lastSendTimeStamp = 0; private final CopyOnWriteArraySet> capabilitiesListeners = new CopyOnWriteArraySet<>(); @@ -342,47 +340,33 @@ public void addWeakCapabilitiesListener(SupportedCapabilitiesListener listener) capabilitiesListeners.add(new WeakReference<>(listener)); } - // TODO either use the argument or delete it - private boolean violatesThrottleLimit(NetworkEnvelope networkEnvelope) { + private boolean violatesThrottleLimit() { long now = System.currentTimeMillis(); - boolean violated = false; - //TODO remove message storage after network is tested stable - if (messageTimeStamps.size() >= msgThrottlePerSec) { - // check if we got more than 200 (MSG_THROTTLE_PER_SEC) msg per sec. - long compareValue = messageTimeStamps.get(messageTimeStamps.size() - msgThrottlePerSec).first; - // if duration < 1 sec we received too much network_messages - violated = now - compareValue < TimeUnit.SECONDS.toMillis(1); - if (violated) { - log.error("violatesThrottleLimit MSG_THROTTLE_PER_SEC "); - log.error("elapsed " + (now - compareValue)); - log.error("messageTimeStamps: \n\t" + messageTimeStamps.stream() - .map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second) - .collect(Collectors.toList()).toString()); - } - } - if (messageTimeStamps.size() >= msgThrottlePer10Sec) { - if (!violated) { - // check if we got more than 50 msg per 10 sec. - long compareValue = messageTimeStamps.get(messageTimeStamps.size() - msgThrottlePer10Sec).first; - // if duration < 10 sec we received too much network_messages - violated = now - compareValue < TimeUnit.SECONDS.toMillis(10); - - if (violated) { - log.error("violatesThrottleLimit MSG_THROTTLE_PER_10_SEC "); - log.error("elapsed " + (now - compareValue)); - log.error("messageTimeStamps: \n\t" + messageTimeStamps.stream() - .map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second) - .collect(Collectors.toList()).toString()); - } + messageTimeStamps.add(now); + + // clean list + while(messageTimeStamps.size() > msgThrottlePer10Sec) + messageTimeStamps.remove(0); + + return violatesThrottleLimit(now,1, msgThrottlePerSec) || violatesThrottleLimit(now,10, msgThrottlePer10Sec); + } + + private boolean violatesThrottleLimit(long now, int seconds, int messageCountLimit) { + if (messageTimeStamps.size() >= messageCountLimit) { + + // find the entry in the message timestamp history which determines whether we overshot the limit or not + long compareValue = messageTimeStamps.get(messageTimeStamps.size() - messageCountLimit); + + // if duration < seconds sec we received too much network_messages + if(now - compareValue < TimeUnit.SECONDS.toMillis(seconds)) { + log.error("violatesThrottleLimit {}/{} second(s)", messageCountLimit, seconds); + + return true; } } - // we limit to max 1000 (MSG_THROTTLE_PER_10SEC) entries - while (messageTimeStamps.size() > msgThrottlePer10Sec) - messageTimeStamps.remove(0); - messageTimeStamps.add(new Tuple2<>(now, networkEnvelope.getClass().getName())); - return violated; + return false; } /////////////////////////////////////////////////////////////////////////////////////////// @@ -747,8 +731,7 @@ public void run() { return; } - if (violatesThrottleLimit(networkEnvelope) - && reportInvalidRequest(RuleViolation.THROTTLE_LIMIT_EXCEEDED)) + if (violatesThrottleLimit() && reportInvalidRequest(RuleViolation.THROTTLE_LIMIT_EXCEEDED)) return; // Check P2P network ID From 03db522a112e1a7b6083cebf0fbf9afa784e4605 Mon Sep 17 00:00:00 2001 From: Florian Reimair Date: Mon, 4 Mar 2019 12:45:53 +0100 Subject: [PATCH 2/3] Remove restart-mechanism from seed node --- seednode/src/main/java/bisq/seednode/SeedNodeMain.java | 1 - 1 file changed, 1 deletion(-) diff --git a/seednode/src/main/java/bisq/seednode/SeedNodeMain.java b/seednode/src/main/java/bisq/seednode/SeedNodeMain.java index c9bb8761292..9f0da7c510b 100644 --- a/seednode/src/main/java/bisq/seednode/SeedNodeMain.java +++ b/seednode/src/main/java/bisq/seednode/SeedNodeMain.java @@ -53,7 +53,6 @@ public static void main(String[] args) throws Exception { protected void doExecute(OptionSet options) { super.doExecute(options); - checkMemory(bisqEnvironment, this); CommonSetup.setup(this); keepRunning(); From 06d21865b6c1363876b3bf436d5be526951b601f Mon Sep 17 00:00:00 2001 From: Florian Reimair Date: Mon, 4 Mar 2019 14:10:07 +0100 Subject: [PATCH 3/3] Added systemd.service for seednode operation --- seednode/README.md | 19 +++++++++++++++++++ seednode/bisq-seednode.service | 14 ++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 seednode/README.md create mode 100644 seednode/bisq-seednode.service diff --git a/seednode/README.md b/seednode/README.md new file mode 100644 index 00000000000..6483a88f770 --- /dev/null +++ b/seednode/README.md @@ -0,0 +1,19 @@ +# Bisq Seed Node + +The distribution ships with a systemd .desktop file. Validate/change the executable/config paths within the shipped `bisq-seednode.service` file and copy/move the file to your systemd directory (something along `/usr/lib/systemd/system/`). Now you can control your *Seed Node* via the usual systemd start/stop commands + +``` +systemctl start bisq-seednode.service +systemctl stop bisq-seednode.service +``` +and +``` +systemctl enable bisq-seednode.service +systemctl disable bisq-seednode.service +``` + +Follow the logs created by the service by inspecting + +``` +journalctl --unit bisq-seednode --follow +``` diff --git a/seednode/bisq-seednode.service b/seednode/bisq-seednode.service new file mode 100644 index 00000000000..095f4968758 --- /dev/null +++ b/seednode/bisq-seednode.service @@ -0,0 +1,14 @@ +[Unit] +Description=Bisq Seed Node +After=network.target + +[Service] +Environment="JAVA_OPTS=-Xms800M -Xmx800M" +ExecStart=/home/bisq/bisq/bisq-seednode --appName=seed_BTC_MAINNET --nodePort=8000 --userDataDir=/home/bisq/ --maxConnections=50 --baseCurrencyNetwork=BTC_MAINNET +Restart=on-failure + +User=bisq +Group=bisq + +[Install] +WantedBy=multi-user.target