From bda4eb830e98ef3506c80ce190aade76fd05a015 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 4 Dec 2009 11:16:43 +0000 Subject: [PATCH] prevent accept() hang on internal socket --- .../router/client/ClientListenerRunner.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/router/java/src/net/i2p/router/client/ClientListenerRunner.java b/router/java/src/net/i2p/router/client/ClientListenerRunner.java index e5e6d8443..2c96fa487 100644 --- a/router/java/src/net/i2p/router/client/ClientListenerRunner.java +++ b/router/java/src/net/i2p/router/client/ClientListenerRunner.java @@ -9,6 +9,7 @@ package net.i2p.router.client; */ import java.io.IOException; +import java.io.InputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; @@ -133,20 +134,24 @@ public class ClientListenerRunner implements Runnable { /** give the i2cp client 5 seconds to show that they're really i2cp clients */ private final static int CONNECT_TIMEOUT = 5*1000; - + + /** + * Verify the first byte. + * The InternalSocket doesn't support SoTimeout, so use available() + * instead to prevent hanging. + */ protected boolean validate(Socket socket) { try { - socket.setSoTimeout(CONNECT_TIMEOUT); - int read = socket.getInputStream().read(); - if (read != I2PClient.PROTOCOL_BYTE) - return false; - socket.setSoTimeout(0); - return true; - } catch (IOException ioe) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Peer did not authenticate themselves as I2CP quickly enough, dropping"); - return false; - } + InputStream is = socket.getInputStream(); + for (int i = 0; i < 20; i++) { + if (is.available() > 0) + return is.read() == I2PClient.PROTOCOL_BYTE; + try { Thread.sleep(250); } catch (InterruptedException ie) {} + } + } catch (IOException ioe) {} + if (_log.shouldLog(Log.WARN)) + _log.warn("Peer did not authenticate themselves as I2CP quickly enough, dropping"); + return false; } /** * Handle the connection by passing it off to a {@link ClientConnectionRunner ClientConnectionRunner}