diff options
Diffstat (limited to 'src/main/java/org/traccar/session')
-rw-r--r-- | src/main/java/org/traccar/session/ConnectionKey.java | 54 | ||||
-rw-r--r-- | src/main/java/org/traccar/session/ConnectionManager.java | 28 | ||||
-rw-r--r-- | src/main/java/org/traccar/session/DeviceSession.java | 6 |
3 files changed, 72 insertions, 16 deletions
diff --git a/src/main/java/org/traccar/session/ConnectionKey.java b/src/main/java/org/traccar/session/ConnectionKey.java new file mode 100644 index 000000000..3b7e2ebf8 --- /dev/null +++ b/src/main/java/org/traccar/session/ConnectionKey.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.session; + +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.util.Objects; + +public class ConnectionKey { + + private final SocketAddress localAddress; + private final SocketAddress remoteAddress; + + public ConnectionKey(Channel channel, SocketAddress remoteAddress) { + this(channel.localAddress(), remoteAddress); + } + + public ConnectionKey(SocketAddress localAddress, SocketAddress remoteAddress) { + this.localAddress = localAddress; + this.remoteAddress = remoteAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConnectionKey that = (ConnectionKey) o; + return Objects.equals(localAddress, that.localAddress) && Objects.equals(remoteAddress, that.remoteAddress); + } + + @Override + public int hashCode() { + return Objects.hash(localAddress, remoteAddress); + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 42dcf5ce9..8431a0327 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -66,8 +66,8 @@ public class ConnectionManager implements BroadcastInterface { private final boolean showUnknownDevices; private final Map<Long, DeviceSession> sessionsByDeviceId = new ConcurrentHashMap<>(); - private final Map<SocketAddress, Map<String, DeviceSession>> sessionsByEndpoint = new ConcurrentHashMap<>(); - private final Map<SocketAddress, String> unknownByEndpoint = new ConcurrentHashMap<>(); + private final Map<ConnectionKey, Map<String, DeviceSession>> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map<ConnectionKey, String> unknownByEndpoint = new ConcurrentHashMap<>(); private final Config config; private final CacheManager cacheManager; @@ -108,8 +108,9 @@ public class ConnectionManager implements BroadcastInterface { Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) throws Exception { + ConnectionKey connectionKey = new ConnectionKey(channel, remoteAddress); Map<String, DeviceSession> endpointSessions = sessionsByEndpoint.getOrDefault( - remoteAddress, new ConcurrentHashMap<>()); + connectionKey, new ConcurrentHashMap<>()); uniqueIds = Arrays.stream(uniqueIds).filter(Objects::nonNull).toArray(String[]::new); if (uniqueIds.length > 0) { @@ -133,23 +134,23 @@ public class ConnectionManager implements BroadcastInterface { } if (device != null) { - unknownByEndpoint.remove(remoteAddress); + unknownByEndpoint.remove(connectionKey); device.checkDisabled(); DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); if (oldSession != null) { - Map<String, DeviceSession> oldEndpointSessions = sessionsByEndpoint.get(oldSession.getRemoteAddress()); + Map<String, DeviceSession> oldEndpointSessions = sessionsByEndpoint.get(oldSession.getConnectionKey()); if (oldEndpointSessions != null && oldEndpointSessions.size() > 1) { oldEndpointSessions.remove(device.getUniqueId()); } else { - sessionsByEndpoint.remove(oldSession.getRemoteAddress()); + sessionsByEndpoint.remove(oldSession.getConnectionKey()); } } DeviceSession deviceSession = new DeviceSession( device.getId(), device.getUniqueId(), device.getModel(), protocol, channel, remoteAddress); endpointSessions.put(device.getUniqueId(), deviceSession); - sessionsByEndpoint.put(remoteAddress, endpointSessions); + sessionsByEndpoint.put(connectionKey, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); if (oldSession == null) { @@ -158,7 +159,7 @@ public class ConnectionManager implements BroadcastInterface { return deviceSession; } else { - unknownByEndpoint.put(remoteAddress, firstUniqueId); + unknownByEndpoint.put(connectionKey, firstUniqueId); LOGGER.warn("Unknown device - " + String.join(" ", uniqueIds) + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); return null; @@ -189,7 +190,8 @@ public class ConnectionManager implements BroadcastInterface { public void deviceDisconnected(Channel channel, boolean supportsOffline) { SocketAddress remoteAddress = channel.remoteAddress(); if (remoteAddress != null) { - Map<String, DeviceSession> endpointSessions = sessionsByEndpoint.remove(remoteAddress); + ConnectionKey connectionKey = new ConnectionKey(channel, remoteAddress); + Map<String, DeviceSession> endpointSessions = sessionsByEndpoint.remove(connectionKey); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { if (supportsOffline) { @@ -199,7 +201,7 @@ public class ConnectionManager implements BroadcastInterface { cacheManager.removeDevice(deviceSession.getDeviceId()); } } - unknownByEndpoint.remove(remoteAddress); + unknownByEndpoint.remove(connectionKey); } } @@ -212,7 +214,7 @@ public class ConnectionManager implements BroadcastInterface { DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); if (deviceSession != null) { cacheManager.removeDevice(deviceId); - sessionsByEndpoint.computeIfPresent(deviceSession.getRemoteAddress(), (e, sessions) -> { + sessionsByEndpoint.computeIfPresent(deviceSession.getConnectionKey(), (e, sessions) -> { sessions.remove(deviceSession.getUniqueId()); return sessions.isEmpty() ? null : sessions; }); @@ -345,9 +347,9 @@ public class ConnectionManager implements BroadcastInterface { } public synchronized void updateLog(LogRecord record) { - var sessions = sessionsByEndpoint.getOrDefault(record.getAddress(), Map.of()); + var sessions = sessionsByEndpoint.getOrDefault(record.getConnectionKey(), Map.of()); if (sessions.isEmpty()) { - String unknownUniqueId = unknownByEndpoint.get(record.getAddress()); + String unknownUniqueId = unknownByEndpoint.get(record.getConnectionKey()); if (unknownUniqueId != null && showUnknownDevices) { record.setUniqueId(unknownUniqueId); listeners.values().stream() diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index f124ca7f9..31d5e6a13 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ public class DeviceSession { return channel; } - public SocketAddress getRemoteAddress() { - return remoteAddress; + public ConnectionKey getConnectionKey() { + return new ConnectionKey(channel, remoteAddress); } public boolean supportsLiveCommands() { |