Cannor process trap by TCP after Bad value notation

Hello!
Please, help me to understand, what is wrong.

I have an SNMP trap listener which is configured to listen via TCP and UDP protocols.

String address = String.format("%s/%d", LISTENING_ADDRESS, port);
TransportMapping udpTransportMapping = new DefaultUdpTransportMapping(new UdpAddress(address));
TransportMapping tcpTransportMapping = new DefaultTcpTransportMapping(new TcpAddress(address));

snmp = new Snmp(mtDispatcher, udpTransportMapping);
snmp.setLocalEngine(localEngineId.getBytes(), 0, 0);
snmp.addTransportMapping(tcpTransportMapping);
snmp.addCommandResponder(this);

The listener correctly receives traps and informs from net-snmp agent. But when I try to send incorrect value (example below), I cannot receive messages by TCP any more (sometimes works after first error). Only by TCP. The UDP protocol continue to work, event if I try to send a lot of traps with wrong value.

sudo snmptrap -v 3 -e 0x6167656e74303037 -u trapuser2 -a MD5 -A password -x DES -X 1234567890123456 -l authPriv tcp:192.168.190.63:8764 “” 1.3.3.3.3.3.3.3 1.2.2.2.2.2.2 a 1.1.1.1.1
1.2.2.2.2.2.2: Bad value notation (1.1.1.1.1)

When this happens, I have no exceptions in my code, and I don’t see any changes in the TransportMapping objects in SNMP instance.

What am I doing wrong?

P.S. I’m using the snmp4j 2.5.0, but also tried with 2.8.0

TCP is different to UDP. With TCP you cannot send “messages”. You send a stream of bytes. If the length of a payload does not correspond to the length of the send stream, the receiver can detect it, but cannot recover the connection (i.e. the message alignment). Thus, SNMP4J will close a connection, if it detects a message encoding error (i.e. incorrect lengths).

Why the NET-SNMP utility does not reopen the TCP connection is unknown to me. It also could be a completely different reason, i.e. that the NET-SNMP tool does not increase its boot-counter.

You can better find out the real reason by activating DEBUG log on both ends.

Thank you for answer.

So, as far as I understand, this is the expected behavior when SNMP4J closes the TCP connection on error. But how can I verify that SNMP4J has closed it? I want to restart my listener or fix it on some other way on encoding error.

I’ve tried to monitor via TransportStateListener, but the state always the same - STATE_CONNECTED -> STATE_DISCONNECTED_REMOTELY. With TransportListener I also didn’t find any helpful information.

Log when data is correct:

Key is acceptable
Adding operation 1 for: SocketEntry[peerAddress=192.168.190.9/47310,socket=Socket[addr=/192.168.190.9,port=47310,localport=8765],lastUse=Mon Jan 12 20:37:02 MSK 1970,readBufferPosition=-1]
Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.DefaultTcpTransportMapping@76182edf,peerAddress=192.168.190.9/47310,newState=1,cancelled=false,causingException=null]
Key is reading
Reading header 6 bytes from 192.168.190.9/47310
Message length is org.snmp4j.transport.MessageLength[headerLength=3,payloadLength=176]
Message completed with 179 bytes and 179 buffer limit
Received message from 192.168.190.9/47310 with length 179: 30:81:b0:02:01:03:30:12:02:04:72:d0:f0:fd:02:04:7f:ff:ff:ff:04:01:03:02:01:03:04:35:30:33:04:08:61:67:65:6e:74:30:30:37:02:01:00:02:01:00:04:09:74:72:61:70:75:73:65:72:31:04:0c:7e:d9:e3:ce:22:79:ff:ed:32:d0:f4:2a:04:08:00:00:03:67:a9:bf:71:bb:04:60:3b:f3:b2:2b:6b:96:09:53:72:0e:10:be:fb:39:88:52:6d:99:03:ee:ff:74:13:2f:57:4f:97:69:99:65:41:8b:d9:39:8b:3c:42:4c:de:f4:e3:64:97:b2:b5:9e:16:ef:47:51:34:12:8e:d9:ee:d7:30:8a:1c:78:d7:08:39:dc:16:3c:72:50:30:ea:8e:46:e1:4a:db:64:1a:40:4e:77:52:77:57:1a:c5:a3:d7:9f:ea:2e:32:a1:48:da:3f:48
Key is readable
Key is reading
SNMPv3 header decoded: msgId=1926295805, msgMaxSize=2147483647, msgFlags=03, secModel=3
Reading header -1 bytes from 192.168.190.9/47310
Socket closed remotely
Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.DefaultTcpTransportMapping@76182edf,peerAddress=192.168.190.9/47310,newState=2,cancelled=false,causingException=null]
RFC3412 §7.2.10 - Received PDU is NOT a response or internal class message -> unchanged PduHandle = PduHandle[330693974]
Fire process PDU event: CommandResponderEvent[securityModel=3, securityLevel=3, maxSizeResponsePDU=2147483465, pduHandle=PduHandle[330693974], stateReference=null, pdu=TRAP[{contextEngineID=80:00:1f:88:80:86:d8:70:4a:06:29:a7:56:00:00:00:00, contextName=}, requestID=330693974, errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.3.0 = 35 days, 21:27:37.23; 1.3.6.1.6.3.1.1.4.1.0 = 1.3.3.3.3.3.3.3; 1.2.2.2.2.2.2 = 1.1.1.1]], messageProcessingModel=3, securityName=trapuser1, processed=false, peerAddress=192.168.190.9/47310, transportMapping=org.snmp4j.transport.DefaultTcpTransportMapping@76182edf, tmStateReference=null]

Log when error:

Key is acceptable
Adding operation 1 for: SocketEntry[peerAddress=192.168.190.9/47316,socket=Socket[addr=/192.168.190.9,port=47316,localport=8765],lastUse=Mon Jan 12 20:37:22 MSK 1970,readBufferPosition=-1]
Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.DefaultTcpTransportMapping@76182edf,peerAddress=192.168.190.9/47316,newState=1,cancelled=false,causingException=null]
Key is reading
Reading header -1 bytes from 192.168.190.9/47316
Socket closed remotely
Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.DefaultTcpTransportMapping@76182edf,peerAddress=192.168.190.9/47316,newState=2,cancelled=false,causingException=null]

Ok, then it is quite simple:
The NET-SNMP client which closes the TCP connection before sending any data.

You need to debug/analyse the NET-SNMP software instead SNMP4J.

Sorry, maybe I describe my problem incorrectly.

With NET-SNMP, this is just an example of how we may receive the wrong message. And there must be some way to restore the state of SNMP4J or just find out that something happened. How can we do this? Maybe by checking some properties of TransportMapping?

Hi, then maybe I do not yet understand the whole story. From the log you posted:

  1. OK case: everything is fine.

  2. NOK case, the message sender (the NET-SNMP client) is closing the connection before sending any/the necessary rest of the data.

Why should there be a “state” in the trap receiver (SNMP4J)?

What could happen BTW, is that the sender closes one of its channels without notifying the peer. In that case, the peer (SNMP4J) will not recognise that the connection is broken although no communication is possible. In that case, keep-alive messages and/or timeouts will recognise the error and close the whole connection.