From 5c99b1d32e697e842ca972c4fb7f0dabbad1e576 Mon Sep 17 00:00:00 2001 From: Albert Vaca Cintora Date: Fri, 4 Aug 2023 08:25:11 +0000 Subject: [PATCH] Avoid starting more than 1 connection to the same device Since we close old connections when a new connection is received, due to race conditions we could end up without a valid connection in this case. Equivalent to https://invent.kde.org/network/kdeconnect-kde/-/merge_requests/580 --- .../Backends/LanBackend/LanLinkProvider.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java index 7ed34001..569176f1 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java @@ -42,6 +42,7 @@ import java.security.cert.Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import javax.net.SocketFactory; import javax.net.ssl.SSLSocket; @@ -64,10 +65,14 @@ public class LanLinkProvider extends BaseLinkProvider { final static int MAX_UDP_PACKET_SIZE = 1024 * 512; + final static long MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE = 500L; + private final Context context; private final HashMap visibleDevices = new HashMap<>(); //Links by device id + final ConcurrentHashMap lastConnectionTime = new ConcurrentHashMap<>(); + private ServerSocket tcpServer; private DatagramSocket udpServer; @@ -118,15 +123,21 @@ public class LanLinkProvider extends BaseLinkProvider { if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) { Log.e("KDE/LanLinkProvider", "Expecting an UDP identity packet"); return; - } else { - String myId = DeviceHelper.getDeviceId(context); - if (deviceId.equals(myId)) { - //Ignore my own broadcast - return; - } } - Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName")); + String myId = DeviceHelper.getDeviceId(context); + if (deviceId.equals(myId)) { + //Ignore my own broadcast + return; + } + + long now = System.currentTimeMillis(); + Long last = lastConnectionTime.get(deviceId); + if (last != null && (last + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE > now)) { + Log.i("LanLinkProvider", "Discarding second UDP packet from the same device " + deviceId + " received too quickly"); + return; + } + lastConnectionTime.put(deviceId, now); int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT); if (tcpPort < MIN_PORT || tcpPort > MAX_PORT) { @@ -134,6 +145,8 @@ public class LanLinkProvider extends BaseLinkProvider { return; } + Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName")); + SocketFactory socketFactory = SocketFactory.getDefault(); Socket socket = socketFactory.createSocket(address, tcpPort); configureSocket(socket);