[SNMP4J] DefaultUdpTransportListener$ListenThread.run does not recover from IOException
Jeff Gehlbach
jeffg at jeffg.org
Fri May 16 02:52:48 CEST 2008
When using a DefaultUdpTransportMapping from SNMP4J 1.8.1, the
ListenThread member's run() method always returns after catching an
IOException:
public void run() {
try {
socket.setSoTimeout(getSocketTimeout());
...
fireProcessMessage(new UdpAddress(packet.getAddress(),
packet.getPort()), bis);
...
}
...
catch (IOException iox) {
logger.warn(iox);
if (logger.isDebugEnabled()) {
iox.printStackTrace();
}
if (SNMP4JSettings.isFowardRuntimeExceptions()) {
throw new RuntimeException(iox);
}
}
}
synchronized (DefaultUdpTransportMapping.this) {
listener = null;
stop = true;
socket.close();
}
}
The upshot of this fact is that if this class is being used as a trap
listener, it's possible to end the listener thread simply by sending
bogus data to the listener port that will cause
fireProcessMessage(...) to throw an IOException. Since SNMP4J eats
the IOException by default, there's no way for the method that created
the trap listener even to know that the listener thread has ended.
I think this catch block for IOException should read like this
instead, so that the listener thread will continue running until told
to stop:
catch (IOException iox) {
logger.warn(iox);
if (logger.isDebugEnabled()) {
iox.printStackTrace();
}
if (SNMP4JSettings.isFowardRuntimeExceptions()) {
throw new RuntimeException(iox);
}
if (!stop) {
run();
}
Does this make sense, or am I missing an obvious way to be informed
about an IOException that happens in this thread? Even enabling
forwardRuntimeExceptions does not seem like a reliable way to detect
this condition, since once my application calls listen() on the
org.snmp4j.Snmp object that has this transport mapping associated with
it, my application has no way to be informed of the problem. Then
again, it's been a long day, so I'll be happy to hear that I've
overlooked something obvious.
-jeff
More information about the SNMP4J
mailing list