[SNMP4J] SocketTimeout task leaks open socket
Frank Fock
fock at agentpp.com
Fri Jan 26 17:09:21 CET 2018
Hi Bruno,
Your use case is indeed special although absolutely valid, of course. The fix seems to be pretty clean and straightforward. I will write a unit test for it and if everything is fine, it will be included in the next release.
Best regards,
Frank
> On 26. Jan 2018, at 17:02, Bruno Abreu <bruno.abreu at livingdata.pt> wrote:
>
> Hello,
>
> we are using snmp4j to handle NTCIP-PMPP protocol which is based in SNMP over
> TCP.
>
> More details about NTCIP-PMPP specification, see:
> http://www.ntcip.org/library/documents/pdf/pmpp01.pdf
>
> In our case, we need to connect to a device that can only accept one
> connection at a time. This lead us to find what we think might be a bug in the
> DefaultTcpTransportMapping class.
>
> Because of that "one connection at a time" requirement, we need to close the
> socket explicitly, immediately after communication with the device is
> finished, so that other clients can connect. The SocketTimeout timer task,
> however, is still scheduled to run after the socket is closed. It will
> eventually execute and, since it holds a reference to a socket that is already
> closed, invoking close() on that socket will cause no harm. The problem is
> that it also removes from the 'sockets' Hashtable any entry that might have
> been created with the same target address of the socket it was supposed to be
> closing.
>
> Since it's possible that a new conversation to the same device is already
> taking place, when a new message is about to be sent out, the
> DefaultTcpTransportMapping doesn't find the entry in the 'sockets' table and
> tries to establish a new connection. From that point on we receive Connection
> refused exceptions.
>
> The following patch succeeded in solving our problem. We submit it here in
> case you want to consider applying to the DefaultTcpTransportMapping class in
> a future release.
>
> »»»
> --- DefaultTcpTransportMapping.java.2.5.11 2018-01-26 11:36:14.019589314 +0000
> +++ DefaultTcpTransportMapping.java 2018-01-26 11:11:42.000000000 +0000
> @@ -258,6 +258,9 @@ public class DefaultTcpTransportMapping
> }
> SocketEntry entry = sockets.remove(remoteAddress);
> if (entry != null) {
> + if (entry.getSocketCleaner() != null) {
> + entry.getSocketCleaner().cancel();
> + }
> Socket s = entry.getSocket();
> if (s != null) {
> SocketChannel sc = entry.getSocket().getChannel();
> @@ -388,7 +391,9 @@ public class DefaultTcpTransportMapping
>
> private synchronized void timeoutSocket(SocketEntry entry) {
> if (connectionTimeout > 0) {
> - socketCleaner.schedule(new SocketTimeout(entry), connectionTimeout);
> + SocketTimeout socketTimeoutCleaner = new SocketTimeout(entry);
> + entry.setSocketCleaner(socketTimeoutCleaner);
> + socketCleaner.schedule(socketTimeoutCleaner, connectionTimeout);
> }
> }
>
> @@ -421,6 +426,7 @@ public class DefaultTcpTransportMapping
> private ByteBuffer readBuffer = null;
> private volatile int registrations = 0;
> private volatile int busyLoops = 0;
> + private SocketTimeout socketCleaner = null;
>
> public SocketEntry(TcpAddress address, Socket socket) {
> this.peerAddress = address;
> @@ -506,6 +512,14 @@ public class DefaultTcpTransportMapping
> busyLoops = 0;
> }
>
> + public SocketTimeout getSocketCleaner() {
> + return socketCleaner;
> + }
> +
> + public void setSocketCleaner(SocketTimeout socketCleaner) {
> + this.socketCleaner = socketCleaner;
> + }
> +
> public String toString() {
> return "SocketEntry[peerAddress="+peerAddress+
> ",socket="+socket+",lastUse="+new
> Date(lastUse/SnmpConstants.MILLISECOND_TO_NANOSECOND)+
> @@ -592,7 +606,9 @@ public class DefaultTcpTransportMapping
> if (logger.isDebugEnabled()) {
> logger.debug("Scheduling " + nextRun);
> }
> - socketCleaner.schedule(new SocketTimeout(entry), nextRun);
> + SocketTimeout socketTimeoutCleaner = new SocketTimeout(entry);
> + entry.setSocketCleaner(socketTimeoutCleaner);
> + socketCleaner.schedule(socketTimeoutCleaner, nextRun);
> }
>
> public boolean cancel(){
> «««
>
>
> That you for you attention,
> Bruno Abreu
>
> --
> Living Data - Sistemas de Informação e Apoio à Decisão, Lda.
> LxFactory - Rua Rodrigues de Faria, 103, edifício I, 4º piso
> 1300-501 LISBOA Phone: +351 213622163
> Portugal URL: www.livingdata.pt
>
>
> _______________________________________________
> SNMP4J mailing list
> SNMP4J at agentpp.org
> https://oosnmp.net/mailman/listinfo/snmp4j
More information about the SNMP4J
mailing list