Fix SNMP traps processing

This commit is contained in:
ViacheslavKlimov 2024-02-06 16:57:52 +02:00
parent 8706bd9c3c
commit cd46ebe53a
2 changed files with 24 additions and 17 deletions

View File

@ -37,7 +37,7 @@ import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols; import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM; import org.snmp4j.security.USM;
import org.snmp4j.smi.Address; import org.snmp4j.smi.IpAddress;
import org.snmp4j.smi.OctetString; import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress; import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress; import org.snmp4j.smi.UdpAddress;
@ -336,15 +336,22 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
* */ * */
@Override @Override
public void processPdu(CommandResponderEvent event) { public void processPdu(CommandResponderEvent event) {
Address sourceAddress = event.getPeerAddress(); IpAddress sourceAddress = (IpAddress) event.getPeerAddress();
DeviceSessionContext sessionContext = transportContext.getSessions().stream() List<DeviceSessionContext> sessions = transportContext.getSessions().stream()
.filter(session -> session.getTarget().getAddress().equals(sourceAddress)) .filter(session -> ((IpAddress) session.getTarget().getAddress()).getInetAddress().equals(sourceAddress.getInetAddress()))
.findFirst().orElse(null); .collect(Collectors.toList());
if (sessionContext == null) { if (sessions.isEmpty()) {
log.warn("SNMP TRAP processing failed: couldn't find device session for address {}", sourceAddress); log.warn("Couldn't find device session for SNMP TRAP for address {}", sourceAddress);
return;
} else if (sessions.size() > 1) {
for (DeviceSessionContext sessionContext : sessions) {
transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), SnmpCommunicationSpec.TO_SERVER_RPC_REQUEST.getLabel(),
new IllegalStateException("Found multiple devices for host " + sourceAddress.getInetAddress().getHostAddress()));
}
return; return;
} }
DeviceSessionContext sessionContext = sessions.get(0);
try { try {
processIncomingTrap(sessionContext, event); processIncomingTrap(sessionContext, event);
} catch (Throwable e) { } catch (Throwable e) {
@ -356,11 +363,11 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
private void processIncomingTrap(DeviceSessionContext sessionContext, CommandResponderEvent event) { private void processIncomingTrap(DeviceSessionContext sessionContext, CommandResponderEvent event) {
PDU pdu = event.getPDU(); PDU pdu = event.getPDU();
if (pdu == null) { if (pdu == null) {
log.warn("Got empty trap from device {}", sessionContext.getDeviceId()); log.warn("[{}] Received empty SNMP trap", sessionContext.getDeviceId());
throw new IllegalArgumentException("Received TRAP with no data"); throw new IllegalArgumentException("Received TRAP with no data");
} }
log.debug("Processing SNMP trap from device {} (PDU: {}}", sessionContext.getDeviceId(), pdu); log.debug("[{}] Processing SNMP trap: {}", sessionContext.getDeviceId(), pdu);
SnmpCommunicationConfig communicationConfig = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() SnmpCommunicationConfig communicationConfig = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream()
.filter(config -> config.getSpec() == SnmpCommunicationSpec.TO_SERVER_RPC_REQUEST).findFirst() .filter(config -> config.getSpec() == SnmpCommunicationSpec.TO_SERVER_RPC_REQUEST).findFirst()
.orElseThrow(() -> new IllegalArgumentException("No config found for to-server RPC requests")); .orElseThrow(() -> new IllegalArgumentException("No config found for to-server RPC requests"));

View File

@ -805,7 +805,7 @@ public class DefaultTransportService extends TransportActivityManager implements
.setEntityIdLSB(deviceId.getId().getLeastSignificantBits()) .setEntityIdLSB(deviceId.getId().getLeastSignificantBits())
.setServiceId(serviceInfoProvider.getServiceId()) .setServiceId(serviceInfoProvider.getServiceId())
.setMethod(method) .setMethod(method)
.setError(ExceptionUtils.getStackTrace(error))) .setError(ExceptionUtils.getRootCauseMessage(error)))
.build(); .build();
try { try {
sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY);